diff --git a/config/config.exs b/config/config.exs index 07936d75..e7ef5839 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1,6 +1,18 @@ use Mix.Config import Cog.Config.Helpers +# ======================================================================== +# Cog Telemetry - By default, Cog is configured to send an event to the +# Operable telemetry service every time it starts. This event contains a +# unique ID (based on the SHA256 of the UUID for your operable bundle) +# and the Cog version number. +# +# If you would like to opt-out of sending this data, you can set the +# COG_TELEMETRY environment variable to "false". +# ======================================================================== + +config :cog, :telemetry, ensure_boolean(System.get_env("COG_TELEMETRY") || true) + # ======================================================================== # Set this to :unenforcing to globally disable all access rules. # NOTE: This is a global setting. diff --git a/lib/cog.ex b/lib/cog.ex index 1af42152..0722a2e4 100644 --- a/lib/cog.ex +++ b/lib/cog.ex @@ -50,6 +50,9 @@ defmodule Cog do Logger.info("Ensuring common templates are up-to-date") Cog.Repository.Templates.refresh_common_templates! + # Send a start event to the Operable telemetry service + Cog.Telemetry.send_event(:start) + {:ok, top_sup} error -> error diff --git a/lib/cog/telemetry.ex b/lib/cog/telemetry.ex new file mode 100644 index 00000000..ea19e12a --- /dev/null +++ b/lib/cog/telemetry.ex @@ -0,0 +1,48 @@ +defmodule Cog.Telemetry do + require Logger + + @telemetry_url "asdf;a8sw3rjasdfkl;asdf" + + def send_event(type) do + if telemetry_enabled do + spawn fn -> + case build_event(type) do + {:ok, event_body} -> + post_telemetry(type, event_body) + end + end + end + end + + defp build_event(:start) do + bundle_id = + "operable" + |> Cog.Queries.Bundles.bundle_id_from_name + |> Cog.Repo.one + + case bundle_id do + nil -> + {:error, "Cannot find ID for embedded bundle."} + bundle_id -> + telemetry_id = Base.encode16(:crypto.hash(:sha256, bundle_id)) + {:ok, version} = :application.get_key(:cog, :vsn) + {:ok, %{ cog: %{ id: telemetry_id, version: to_string(version) }}} + end + end + + defp telemetry_enabled do + Application.fetch_env!(:cog, :telemetry) + end + + defp post_telemetry(event_type, event_body) do + post_url = @telemetry_url <> "/events/" <> Atom.to_string(event_type) + post_body = Poison.encode!(event_body) + + Logger.info "Sending telemetry data to Operable: #{post_body}" + Logger.info "To disable telemetry, set the COG_TELEMETRY environment variable to false." + + HTTPotion.post(post_url, headers: ["Content-Type": "application/json", + "Accepts": "application/json"], + body: post_body) + end +end