defmodule ExInsights do
@moduledoc """
Exposes methods for POST events & metrics to Azure Application Insights.
For more information on initialization and usage consult the [README.md](readme.html)
"""
alias ExInsights.{Envelope, Utils}
alias ExInsights.Telemetry.{
Types,
EventTelemetry,
TraceTelemetry,
ExceptionTelemetry,
MetricTelemetry,
DependencyTelemetry,
RequestTelemetry
}
@typedoc """
Azure application insights instrumentation key (string) or nil
"""
@type instrumentation_key :: Types.instrumentation_key() | nil
@doc ~S"""
Log a user action or other occurrence.
`name`: name of the event (string or atom)
`properties` (optional): a map of [string -> string] pairs for adding extra properties to this event
`measurements` (optional): a map of [string -> number] values associated with this event that can be aggregated/sumed/etc. on the UI
`tags` (optional): map[string, string] - additional application insights tag metadata.
`instrumentation_key` (optional): Azure application insights API key. If not set it will the default one provided to the `ExInsights.Worker` will be used (see README.md)
"""
@spec track_event(
name :: Types.name(),
properties :: Types.properties(),
measurements :: Types.measurements(),
tags :: Types.tags(),
instrumentation_key :: instrumentation_key
) :: :ok
def track_event(
name,
properties \\ %{},
measurements \\ %{},
tags \\ %{},
instrumentation_key \\ nil
) do
name
|> EventTelemetry.new(properties: properties, measurements: measurements, tags: tags)
|> track(instrumentation_key)
end
@doc ~S"""
Log a trace message.
`message`: A string to identify this event in the portal.
`severity_level`: The level of severity for the event.
`properties`: map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty.
`tags` (optional): map[string, string] - additional application insights tag metadata.
`instrumentation_key` (optional): Azure application insights API key. If not set it will the default one provided to the `ExInsights.Worker` will be used (see README.md)
"""
@spec track_trace(
String.t(),
severity_level :: Types.severity_level(),
properties :: Types.properties(),
tags :: Types.tags(),
instrumentation_key :: instrumentation_key
) :: :ok
def track_trace(
message,
severity_level \\ :info,
properties \\ %{},
tags \\ %{},
instrumentation_key \\ nil
) do
message
|> TraceTelemetry.new(severity_level: severity_level, properties: properties, tags: tags)
|> track(instrumentation_key)
end
@doc ~S"""
Log an exception you have caught.
`exception`: An Error from a catch clause, or the string error message.
`stack_trace`: An erlang stacktrace.
`properties`: map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty.
`measurements`: map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty.
`tags` (optional): map[string, string] - additional application insights tag metadata.
`instrumentation_key` (optional): Azure application insights API key. If not set it will the default one provided to the `ExInsights.Worker` will be used (see README.md)
"""
@spec track_exception(
Exception.t() | String.t(),
stack_trace :: Exception.stacktrace(),
String.t() | nil,
properties :: Types.properties(),
measurements :: Types.measurements(),
tags :: Types.tags(),
instrumentation_key :: instrumentation_key
) :: :ok
def track_exception(
exception,
stack_trace,
handled_at \\ nil,
properties \\ %{},
measurements \\ %{},
tags \\ %{},
instrumentation_key \\ nil
) do
exception
|> ExceptionTelemetry.new(
stack_trace: stack_trace,
handled_at: handled_at,
properties: properties,
measurements: measurements,
tags: tags
)
|> track(instrumentation_key)
end
@doc ~S"""
Log a numeric value that is not associated with a specific event.
Typically used to send regular reports of performance indicators.
`name`: name of the metric
`value`: the value of the metric (number)
`properties` (optional): a map of [string -> string] pairs for adding extra properties to this event
`tags` (optional): map[string, string] - additional application insights tag metadata.
`instrumentation_key` (optional): Azure application insights API key. If not set it will the default one provided to the `ExInsights.Worker` will be used (see README.md)
"""
@spec track_metric(
name :: Types.name(),
value :: number(),
properties :: Types.properties(),
tags :: Types.tags(),
instrumentation_key :: instrumentation_key
) :: :ok
def track_metric(name, value, properties \\ %{}, tags \\ %{}, instrumentation_key \\ nil) do
name
|> MetricTelemetry.new(value, properties: properties, tags: tags)
|> track(instrumentation_key)
end
@doc ~S"""
Log a dependency, for example requests to an external service or SQL calls.
`name`: String that identifies the dependency.
`data`: String of the name of the command made against the dependency (eg. full URL with querystring or SQL command text).
`start_time`: The datetime when the dependency call was initiated.
`duration`: Remote call duration in ms (non-neg integer)
`success?`: True if remote call was successful, false otherwise (boolean).
`dependency_type_name`: Type name of the telemetry, such as HTTP or SQL (string).
`target`: String of the target host of the dependency.
`properties` (optional): map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty.
`id` (optional): a unique identifier representing the dependency call.
`tags` (optional): map[string, string] - additional application insights tag metadata.
`instrumentation_key` (optional): Azure application insights API key. If not set it will the default one provided to the `ExInsights.Worker` will be used (see README.md)
"""
@spec track_dependency(
name :: Types.name(),
data :: String.t(),
start_time :: DateTime.t(),
Types.millisecond(),
boolean(),
String.t(),
String.t() | nil,
properties :: Types.properties(),
id :: binary() | nil,
tags :: Types.tags(),
instrumentation_key :: instrumentation_key
) :: :ok
def track_dependency(
name,
data,
start_time,
duration,
success?,
dependency_type_name \\ "",
target \\ nil,
properties \\ %{},
id \\ nil,
tags \\ %{},
instrumentation_key \\ nil
) do
id = if id == nil, do: Utils.generate_id(), else: id
name
|> DependencyTelemetry.new(id, duration, success?,
dependency_type_name: dependency_type_name,
data: data,
time: start_time,
target: target,
properties: properties,
tags: tags
)
|> track(instrumentation_key)
end
@doc ~S"""
Log an _incoming_ request, for example incoming HTTP requests
`name`: String that identifies the request
`url`: Request URL
`source`: Request Source. Encapsulates info about the component that initiated the request (can be nil)
`start_time`: The datetime when the request was initiated.
`elapsed_time_ms`: Number for elapsed time in milliseconds
`response_code`: Result code reported by the application
`success?`: whether the request was successfull
`properties` (optional): map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty.
`measurements` (optional): a map of [string -> number] values associated with this event that can be aggregated/sumed/etc. on the UI
`id` (optional): a unique identifier representing the request.
`tags` (optional): map[string, string] - additional application insights tag metadata.
`instrumentation_key` (optional): Azure application insights API key. If not set it will the default one provided to the `ExInsights.Worker` will be used (see README.md)
"""
@spec track_request(
name :: Types.name(),
url :: String.t(),
source :: String.t() | nil,
start_time :: DateTime.t(),
elapsed_time_ms :: Types.millisecond(),
response_code :: String.t() | number(),
success? :: boolean(),
properties :: Types.properties(),
measurements :: Types.measurements(),
id :: binary() | nil,
tags :: Types.tags(),
instrumentation_key :: instrumentation_key()
) ::
:ok
def track_request(
name,
url,
source,
start_time,
elapsed_time_ms,
response_code,
success?,
properties \\ %{},
measurements \\ %{},
id \\ nil,
tags \\ %{},
instrumentation_key \\ nil
) do
(id || Utils.generate_id())
|> RequestTelemetry.new(name, url, source, elapsed_time_ms, success?,
time: start_time,
response_code: response_code,
measurements: measurements,
properties: properties,
tags: tags
)
|> track(instrumentation_key)
end
@spec track(Envelope.telemetry(), instrumentation_key()) :: :ok
defp track(telemetry, instrumentation_key)
defp track(telemetry, instrumentation_key) do
# when instrumentation_key is not explicitly set by the caller (default is nil)
# the wrapping into an envelope will happen here but the instrumentation key
# will be later set inside the `ExInsights.Worker` using the startup args
telemetry
|> Envelope.wrap(instrumentation_key)
|> ExInsights.Worker.track()
end
end