Kaizen-Gaming / ex_insights

Elixir client library to log telemetry data on Azure Application Insights

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ExInsights

Hex.pm

Elixir client library to log telemetry data on Azure Application Insights.

Installation

Install from hex by adding ex_insights to your list of dependencies in mix.exs:

def deps do
  [
    {:ex_insights, "~> 0.8"}
  ]
end

You then need to start the ExInsights.Supervisor in your supervision tree. Example:

# inside the init/1 callback of a supervisor in your supervision tree (or start/2 of application.ex)

children = [
  # ...
  {ExInsights.Supervisor, instrumentation_key: "0000-1111-2222-3333"}
]

Supervisor.init(children, strategy: :one_for_one)

Note

For migrating to 0.8.x and later versions read the migration instructions below

Configuration

ExInsights supports the following configuration options you can set when starting the ExInsights.Supervisor

  • :instrumentation_key: You can set the instrumentation key (Azure App Insights secret key) to use for sending data to Azure. It can be overriden on each ExInsights.track_xxx request. Needs to be present either by setting it here or on every request, otherwise the code will raise with an error (string)
  • :flush_inteval_secs: the number of seconds every which the client will send the telemetry data to Azure. Default is every 30 seconds since the last flushing (non-negative integer)
  • :client_module: the module to use for actually sending the requests. Mostly useful in tests (atom)

Example:

options = [
  instrumentation_key: "0000-1111-2222-3333",
  flush_interval_secs: 30
]

children = [
  # ...
  {ExInsights.Supervisor, options}
]

Supervisor.init(children, strategy: :one_for_one)

Usage

Basic Usage

All public tracking methods are under the ExInsights module. Examples:

# will post a click custom_event to azure
ExInsights.track_event("click")

# with custom defined property "type" and measurement "count"
ExInsights.track_event("click", %{type: "button"}, %{count: 2})

# send custom metric data. Does not support aggregated data (count/stdDev, min, max)
ExInsights.track_metric("bananas", 10)

# log arbitrary data
ExInsights.track_trace("1-2-3 boom", :warning)

# log time taken for requests to external resources, eg. database or http service calls
ExInsights.track_dependency("get_user_balance", "http://my.api/get_balance/aviator1", 1500, true, "user", "my.api")

# log telemetry data about the incoming request processed by the application
ExInsights.track_request("homepage", "http://my.site.com/", "HomePageComponent", 85, 200, true)

For more details and optional arguments look at the ExInsights module documentation.

Alternative usage

You can also decorate methods you need to track using decorators.

# Make sure to add the following line before using any decorators
use ExInsights.Decoration.Attributes

# add the @decorate track_xxx() attribute right above each function you need to track

@decorate track_event() # will log the "update_user_email" event in AppInsights on function entry
def update_user_email(email, user) do
  # ...
end

@decorate track_dependency("user-actions") # put under dependency type:user-actions in AppInsights UI
def login_user(user) do
  # ... maybe call external api here
end

@decorate track_exception() # will track errors and exits
def dangerous_stuff do
  # ... do work that may fail
end

Migrating from 0.7.x to 0.8.x

In order to make the library configuration more flexible and in accordance to library development guidelines for configuration, support for configuring the client by setting options directly inside config.exs files was dropped and configuration now needs to happen on supervisor startup.

For example instead of globally configuring ex_insights inside config.exs,

# No longer supported
config :ex_insights,
  instrumentation_key: "0000-1111-2222-3333"

you now need to pass this option to the ExInsights.Supervisor directly instead

children = [
  ...
  {ExInsights.Supervisor, instrumentation_key: "0000-1111-2222-3333"}
]

If you need to keep reading this value from your config files you can still do something like this

# in config.exs
config :my_app, ex_insights_instrumentation_key: "0000-1111-2222-3333"

# in you supervisor.ex file
def read_instrumentation_key_from_config do
  Application.get_env(:my_app, :ex_insights_instrumentation_key)
end

def init(_) do
  ...
  children = [
    # ...
    {ExInsights.Supervisor, instrumentation_key: read_instrumentation_key_from_config()}
  ]
end

Inner workings

  • Calling any tracking function ExInsights.track_xxx from your code will not immediately send the data to Azure. It will instead be aggregated in memory until the flush_timer is triggered (every 30 secs, configurable) and the data will be batch sent.
  • When the application shuts down it will attempt to flush any remaining data.
  • If you are behind a firewall (usually happens in production deployments) make sure your network rules allow HTTP POSTs to https://dc.services.visualstudio.com
  • If requests to azure tracking services fail (network or server errors or bad requests) you will not be alerted.
  • track_dependency and track_exception decorators will try to rescue/catch any errors (and log those) and then re-raise the error / exit as appropriate. This is a different (but hopefully working) approach than what the AppSignal guys do (a separate process monitoring crashes)

About

Elixir client library to log telemetry data on Azure Application Insights

License:MIT License


Languages

Language:Elixir 100.0%