Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: OpenAPI routes updating - Ingestion, Querying #1702

Merged
merged 6 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/docs.logflare.com/docs/concepts/endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ GET https://api.logflare.app/api/endpoints/query/my.custom.endpoint

Querying by name requires authentication to be enabled and for a valid access token to be provided.

OpenAPI documentation for querying Logflare Endpoints can be found [here](https://logflare.app/swaggerui#/Public).

## Crafting a Query

Queries will be passed to the underlying backend to perform the querying.
Expand Down
2 changes: 2 additions & 0 deletions docs/docs.logflare.com/docs/concepts/ingestion/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ POST https://api.logflare.app/api/logs?source=9dd9a6f6-8e9b-4fa4-b682-4f2f5cd99d
POST https://api.logflare.app/api/logs?source_name=my.logs.source
```

OpenAPI documentation for ingestion can be found [here](https://logflare.app/swaggerui#/Public).

### Batching Your Events

You can ingest events individually, or via a batch.
Expand Down
8 changes: 7 additions & 1 deletion lib/logflare_web/api_spec.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@ defmodule LogflareWeb.ApiSpec do
title: to_string(Application.spec(:logflare, :description)),
version: to_string(Application.spec(:logflare, :vsn))
},
paths: Paths.from_router(Router),
paths: Paths.from_router(Router) |> filter_routes(),
components: %Components{
securitySchemes: %{
"authorization" => %SecurityScheme{type: "http", scheme: "bearer", bearerFormat: "JWT"}
}
}
})
end

defp filter_routes(routes_map) do
for {"/api" <> _path = k, v} <- routes_map, into: %{} do
{k, v}
end
end
end
25 changes: 25 additions & 0 deletions lib/logflare_web/controllers/endpoints_controller.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
defmodule LogflareWeb.EndpointsController do
use LogflareWeb, :controller
use OpenApiSpex.ControllerSpecs

require Logger
alias Logflare.Endpoints

alias LogflareWeb.OpenApi.ServerError
alias LogflareWeb.OpenApiSchemas.EndpointQuery

action_fallback(LogflareWeb.Api.FallbackController)
tags(["Public"])

plug CORSPlug,
origin: "*",
Expand All @@ -18,6 +24,25 @@ defmodule LogflareWeb.EndpointsController do
methods: ["GET", "POST", "OPTIONS"],
send_preflight_response?: true

operation(:query,
summary: "Query a Logflare Endpoint",
description:
"Full details are available in the [Logflare Endpoints documentation](https://docs.logflare.app/concepts/endpoints/)",
parameters: [
token_or_name: [
in: :path,
description: "Endpoint UUID or name",
type: :string,
example: "a040ae88-3e27-448b-9ee6-622278b23193",
required: true
]
],
responses: %{
200 => EndpointQuery.response(),
500 => ServerError.response()
}
)

def query(%{assigns: %{endpoint: endpoint}} = conn, _params) do
endpoint_query = Endpoints.map_query_sources(endpoint)

Expand Down
35 changes: 35 additions & 0 deletions lib/logflare_web/controllers/log_controller.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
defmodule LogflareWeb.LogController do
use LogflareWeb, :controller
use OpenApiSpex.ControllerSpecs

alias Logflare.Logs.IngestTypecasting
alias Logflare.Backends

alias LogflareWeb.OpenApi.Created
alias LogflareWeb.OpenApi.ServerError
alias LogflareWeb.OpenApiSchemas.LogsCreated

action_fallback(LogflareWeb.Api.FallbackController)

tags(["Public"])

plug(
CORSPlug,
[
Expand All @@ -25,6 +34,32 @@ defmodule LogflareWeb.LogController do

@message "Logged!"

operation(:create,
summary: "Create log event",
description:
"Full details are available in the [ingestion documentation](https://docs.logflare.app/concepts/ingestion/)",
parameters: [
source: [
in: :query,
description: "Source UUID",
type: :string,
example: "a040ae88-3e27-448b-9ee6-622278b23193",
required: false
],
source_name: [
in: :query,
description: "Source name",
type: :string,
example: "MyApp.MySource",
required: false
]
],
responses: %{
201 => Created.response(LogsCreated),
500 => ServerError.response()
}
)

def create(%{assigns: %{source: source}} = conn, %{"batch" => batch}) when is_list(batch) do
ingest_and_render(conn, batch, source)
end
Expand Down
7 changes: 7 additions & 0 deletions lib/logflare_web/open_api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,11 @@ defmodule LogflareWeb.OpenApi do

def response(), do: {"Not found", "text/plain", __MODULE__}
end

defmodule ServerError do
require OpenApiSpex
OpenApiSpex.schema(%{})

def response(), do: {"Server error", "text/plain", __MODULE__}
end
end
21 changes: 21 additions & 0 deletions lib/logflare_web/open_api_schemas.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
defmodule LogflareWeb.OpenApiSchemas do
alias OpenApiSpex.Schema

defmodule EndpointQuery do
@properties %{
result: %Schema{type: :string, example: "Logged!"},
errors: %Schema{
required: false,
oneOf: [
%Schema{type: :object},
%Schema{type: :string}
]
}
}
use LogflareWeb.OpenApi, properties: @properties, required: []
end

defmodule LogsCreated do
@properties %{
message: %Schema{type: :string, example: "Logged!"}
}
use LogflareWeb.OpenApi, properties: @properties, required: []
end

defmodule Endpoint do
@properties %{
token: %Schema{type: :string},
Expand Down