CloudWatch metrics without API calls, using the Embedded Metric Format: one JSON line on stdout that CloudWatch Logs turns into metrics.
Mayfly.Metrics.emit("MyApp", %{"OrdersPlaced" => 1, "CartValue" => {129.5, "None"}},
dimensions: %{"Tenant" => tenant},
properties: %{"orderId" => id})
Mayfly.Metrics.count("MyApp", "Retries", 2, dimensions: %{"Queue" => "orders"})
Mayfly.Metrics.timing("MyApp", "DbLatency", 42) # MillisecondsInvocation metrics
Attach once (in init/1) and every invocation emits Duration
(Milliseconds), Errors (0/1) and ColdStart (1 on the first invocation of
an execution environment, 0 afterwards) with the dimension FunctionName:
def init(_opts) do
Mayfly.Metrics.attach_invocation_metrics("MyApp")
{:ok, nil}
endRequires the optional :telemetry dependency.
Why not Logger?
CloudWatch parses EMF from the raw log line, which must be a single,
standalone JSON object. Mayfly.LogFormatter wraps messages in its own
object, so metrics are written straight to stdout with IO.puts/2.
Lambda captures stdout into the function's log stream.
Summary
Functions
Attaches a :telemetry handler to [:mayfly, :invocation, :stop] that emits
Duration, Errors and ColdStart under namespace with dimension
FunctionName. Safe to call once per environment; returns {:error, :already_exists}
if attached twice. Returns {:error, :telemetry_not_available} without the dep.
Attaches a :telemetry handler to [:mayfly, :platform, :report] (emitted by
Mayfly.Extension when the extension is enabled) that publishes Lambda's
own numbers as EMF metrics under namespace, dimension FunctionName:
Duration, BilledDuration, MaxMemoryUsed, MemorySize, and
InitDuration when present (cold starts). Unlike
attach_invocation_metrics/2, Duration here is what Lambda measured and
BilledDuration is what you pay for. The report for an invocation arrives
after that invocation has finished, attributed by requestId.
Builds the EMF record without writing it. Raises ArgumentError on invalid
units or too many dimensions/metrics.
Emits a Count metric.
Emits one EMF record. metrics maps names to values or {value, unit}.
Emits a Milliseconds metric.
Types
Functions
Attaches a :telemetry handler to [:mayfly, :invocation, :stop] that emits
Duration, Errors and ColdStart under namespace with dimension
FunctionName. Safe to call once per environment; returns {:error, :already_exists}
if attached twice. Returns {:error, :telemetry_not_available} without the dep.
Attaches a :telemetry handler to [:mayfly, :platform, :report] (emitted by
Mayfly.Extension when the extension is enabled) that publishes Lambda's
own numbers as EMF metrics under namespace, dimension FunctionName:
Duration, BilledDuration, MaxMemoryUsed, MemorySize, and
InitDuration when present (cold starts). Unlike
attach_invocation_metrics/2, Duration here is what Lambda measured and
BilledDuration is what you pay for. The report for an invocation arrives
after that invocation has finished, attributed by requestId.
Builds the EMF record without writing it. Raises ArgumentError on invalid
units or too many dimensions/metrics.
Emits a Count metric.
Emits one EMF record. metrics maps names to values or {value, unit}.
Options:
:dimensions– map of up to 30 string pairs; one dimension set:properties– extra non-metric fields (searchable in Logs Insights):unit– default unit for plain numbers (default"Count"):high_resolution–truefor 1-second storage resolution:timestamp– Unix ms (default now):device– IO device (default:stdio; tests pass a StringIO)
Emits a Milliseconds metric.