defmodule Membrane.Telemetry do
@moduledoc """
Defines basic telemetry event types used by Membrane's Core.
Membrane uses [Telemetry Package](https://hex.pm/packages/telemetry) for instrumentation and does not store or save any measurements by itself.
It is user's responsibility to use some sort of metrics reporter
that will be attached to `:telemetry` package to consume and process generated measurements.
## Instrumentation
The following events are published by Membrane's Core with following measurement types and metadata:
* `[:membrane, :metric, :value]` - used to report metrics, such as input buffer's size inside functions, incoming events and received stream format
* Measurement: `t:metric_event_value/0`
* Metadata: `%{}`
* `[:membrane, :link, :new]` - to report new link connection being initialized in pipeline.
* Measurement: `t:link_event_value/0`
* Metadata: `%{}`
* `[:membrane, :pipeline | :bin | :element, :init]` - to report pipeline/element/bin initialization
* Measurement: `t:init_or_terminate_event_value/0`
* Metadata: `%{log_metadata: keyword()}`, includes Logger's metadata of created component
* `[:membrane, :pipeline | :bin | :element, :terminate]` - to report pipeline/element/bin termination
* Measurement: `t:init_or_terminate_event_value/0`
* Metadata: `%{}`
## Enabling certain metrics/events
A lot of events can happen literally hundreds times per second such as registering that a buffer has been sent/processed.
This behaviour can come with a great performance penalties but may be helpful for certain discoveries. To avoid any runtime overhead
when the reporting is not necessary all metrics/events are hidden behind a compile-time feature flags.
To enable a particular measurement one must recompile membrane core with the following snippet put inside
user's application `config.exs` file:
config :membrane_core,
telemetry_flags: [
:flag_name,
...,
{:metrics, [list of metrics]}
...
]
Available flags are (those are of a very low overhead):
* `:links` - enables new links notifications
* `:inits_and_terminates` - enables notifications of `init` and `terminate` events for elements/bins/pipelines
Additionally one can control which metric values should get measured by passing an option of format :
`{:metrics, [list of metrics]}`
Available metrics are:
* `:buffer` - number of buffers being sent from a particular element
* `:bitrate` - total number of bits carried by the buffers mentioned above
* `:queue_len` - number of messages in element's message queue during GenServer's `handle_info` invocation
* `:stream_format` - indicates that given element has received new stream format, value always equals '1'
* `:event` - indicates that given element has received a new event, value always equals '1'
* `:store` - reports the current size of a input buffer when storing a new buffer
* `:take_and_demand` - reports the current size of a input buffer when taking buffers and making a new demand
"""
@type event_name :: [atom(), ...]
@typedoc """
* component_path - element's or bin's path
* metric - metric's name
* value - metric's value
"""
@type metric_event_value :: %{
component_path: String.t(),
metric: String.t(),
value: integer()
}
@typedoc """
* path - element's path
"""
@type init_or_terminate_event_value :: %{
path: Membrane.ComponentPath.path()
}
@typedoc """
* parent_path - process path of link's parent
* from - from element name
* to - to element name
* pad_from - from's pad name
* pad_to - to's pad name
"""
@type link_event_value :: %{
parent_path: String.t(),
from: String.t(),
to: String.t(),
pad_from: String.t(),
pad_to: String.t()
}
end