Powered by AppSignal & Oban Pro

Logpoint API

logpoint-api.livemd

Logpoint API

Mix.install(
  [
    {:kino, "~> 0.14.2"},
    {:logpoint_api, "~> 2.0"}     
  ],
  consolidate_protocols: false
)

Search API

This is the Logpoint API for creating searches and retrieve the results, but also the API that can give information about Logpoint instances.

ip_input = Kino.Input.text("Logpoint Instance URL")
username_input = Kino.Input.text("Logpoint Username")
secret_key_input = Kino.Input.text("Secret Key Env. Var")

Kino.render(ip_input)
Kino.render(username_input)
Kino.render(secret_key_input)

url = Kino.Input.read(ip_input)
username = Kino.Input.read(username_input)
secret_key = Kino.Input.read(secret_key_input)

"Form Rendered"
client = LogpointApi.client(url, username, System.fetch_env!(secret_key), ssl_verify: false)

getalloweddata

This gives access to information about a Logpoint instance and all the data available to it. Furthermore it can retrieve information related to the live searches used by a particular instance.

Getting User Timezone

This will retrieve the timezone and time format.

{:ok, result} = LogpointApi.Core.Search.user_preference(client)

Kino.DataTable.new([result])

Getting Logpoints

This retrieves the names and IP addresses of all the Logpoints configured in a distributed setup.

{:ok, result} = LogpointApi.Core.Search.loginspects(client)

result
|> Map.get("allowed_loginspects")
|> Kino.DataTable.new()

Getting Repos

This retrieves the name and IP addresses of all the repos configured in a Logpoint instance.

{:ok, result} = LogpointApi.Core.Search.logpoint_repos(client)

result
|> Map.get("allowed_repos")
|> Kino.DataTable.new()

Getting Devices

This retrieves all the names and IP addresses of all the devices configured in a Logpoint instance.

{:ok, result} = LogpointApi.Core.Search.devices(client)

Map.get(result, "allowed_devices")
|> hd
|> Enum.map(fn {key, value} -> %{"name" => value, "ip" => key} end)
|> Kino.DataTable.new()

Getting LiveSearches

This retrieves the information related to the live searches performed for dashboards and alerts.

{:ok, result} = LogpointApi.Core.Search.livesearches(client)

Map.get(result, "livesearches")
|> Kino.Tree.new()

getsearchlogs

Requesting a Search ID

Before we can retrieve results we need to create a search. By creating a search we will receive a search id, which can be used to retrieve the results. The search id is temporary and will be forgotten after some time and if retrieved to early it will return final = false.

query = Kino.Input.text("Logpoint Query")
request_data = LogpointApi.search_params(
  Kino.Input.read(query),
  "Last 24 hours",
  100_000,
  ["127.0.0.1:5504"]
)

{:ok, search_result} = LogpointApi.Core.Search.get_id(client, request_data)

Getting search results

{:ok, result} = LogpointApi.Core.Search.get_result(client, Map.get(search_result, "search_id"))
rows = Map.get(result, "rows")

all_keys =
  rows
  |> Enum.map(&Map.keys/1)
  |> Enum.map(&MapSet.new/1)
  |> Enum.reduce(MapSet.new(), &MapSet.union(&2, &1))

normalized_maps =
  rows
  |> Enum.map(fn map ->
    Enum.reduce(all_keys, map, fn key, acc ->
      Map.put_new(acc, key, nil)
    end)
  end)

# normalized_maps =
#  normalized_maps
#  |> Enum.filter(fn map -> Map.get(map, "country") != nil end)

Kino.DataTable.new(normalized_maps)

Poll Search Results

query = Kino.Input.text("Logpoint Query")
request_data = LogpointApi.search_params(
  Kino.Input.read(query),
  "Last 24 hours",
  100_000,
  ["127.0.0.1:5504"]
)

LogpointApi.run_search(client, request_data)

Incident API

Getting the incidents within a specific time period

LogpointApi.Core.Incident.list(client, 1_714_100_000, :os.system_time(:millisecond))

Getting the incident states

LogpointApi.Core.Incident.list_states(client, 1_714_100_000, :os.system_time(:millisecond))

Getting the data for a single incident

{:ok, incidents} = LogpointApi.Core.Incident.list(client, 1_714_100_000, :os.system_time(:millisecond))

latest = incidents |> Map.get("incidents") |> List.last()
{:ok, result} = LogpointApi.Core.Incident.get(client, latest["id"], latest["incident_id"])

case Map.get(result, "rows") do
  nil -> result |> Kino.Tree.new()
  rows -> rows |> Kino.DataTable.new()
end

Adding incident comments

comment = LogpointApi.comment("6628bcba248b50d05d38d23e", "Comment")
LogpointApi.Core.Incident.add_comments(client, [comment])

Getting Incident Users and User Groups

LogpointApi.Core.Incident.get_users(client)

Assign Incident

LogpointApi.Core.Incident.assign(client, ["6628bcba248b50d05d38d23e"], "6576dedc81777a77c57723e5")

Resolve Incidents

LogpointApi.Core.Incident.resolve(client, ["662ba226248b50d05d38d278"])

Close Incidents

LogpointApi.Core.Incident.close(client, ["662ba226248b50d05d38d278"])

Reopen Incidents

LogpointApi.Core.Incident.reopen(client, ["662ba226248b50d05d38d278"])

Alert Rules API

Manage alert rules including listing, creating, activating, deactivating, and deleting rules. This API uses JWT authentication.

Listing Alert Rules

{:ok, result} = LogpointApi.Core.AlertRule.list(client)
Kino.Tree.new(result)

Getting a Single Alert Rule

{:ok, rules} = LogpointApi.Core.AlertRule.list(client)

rule_id =
  rules
  |> Map.get("rows", [])
  |> List.first()
  |> Map.get("id")

{:ok, rule} = LogpointApi.Core.AlertRule.get(client, rule_id)
Kino.Tree.new(rule)

Creating an Alert Rule

alias LogpointApi.Data.Rule

rule =
  LogpointApi.rule("Test Alert Rule")
  |> Rule.description("Created from Livebook")
  |> Rule.query("error_code=4625")
  |> Rule.time_range(10)
  |> Rule.repos(["127.0.0.1:5504/_logpoint"])
  |> Rule.limit(100)
  |> Rule.threshold(:greaterthan, 5)
  |> Rule.risk_level("high")
  |> Rule.aggregation_type("max")
  |> Rule.assignee("admin")

LogpointApi.Core.AlertRule.create(client, rule)

Activate / Deactivate Alert Rules

# LogpointApi.Core.AlertRule.activate(client, ["rule-id"])
LogpointApi.Core.AlertRule.deactivate(client, ["69a81f07dd02026b52fe05bb"])

Deleting Alert Rules

LogpointApi.Core.AlertRule.delete(client, ["69a81f3bdd02026b52fe05bd"])

Alert Notifications

Create email and HTTP notifications for alert rules.

Creating an Email Notification

alias LogpointApi.Data.EmailNotification

notif =
  LogpointApi.email_notification(["69a81f3bdd02026b52fe05bd"], "admin@example.com")
  |> EmailNotification.subject("Alert: {{ rule_name }}")
  |> EmailNotification.template("

Alert details here

"
) LogpointApi.Core.AlertRule.create_email_notification(client, notif)

Creating an HTTP Notification

alias LogpointApi.Data.HttpNotification

webhook =
  LogpointApi.http_notification(["69a81f3bdd02026b52fe05bd"], "https://hooks.example.com/webhook", :post)
  |> HttpNotification.body(~s({"text": "Alert: {{ rule_name }}"}))
  |> HttpNotification.no_auth()

LogpointApi.Core.AlertRule.create_http_notification(client, webhook)

Getting Alert Notifications

LogpointApi.Core.AlertRule.get_notification(client, "69a81f3bdd02026b52fe05bd", :email)
LogpointApi.Core.AlertRule.get_notification(client, "69a81f3bdd02026b52fe05bd", :http)

Logpoint Repos API

List all searchable logpoints with their repos. This uses JWT authentication.

Listing Logpoint Repos

{:ok, result} = LogpointApi.Core.LogpointRepo.list(client)
Kino.Tree.new(result)

User-Defined Lists API

Manage user-defined lists used for enrichment and filtering in Logpoint.

Listing User-Defined Lists

{:ok, result} = LogpointApi.Core.UserDefinedList.list(client)
Kino.Tree.new(result)

Importing a Static List

# csv_content = "value1\nvalue2\nvalue3"
# LogpointApi.Core.UserDefinedList.import_static(client, "my-list", csv_content)