Packages
timber
2.4.0
3.1.2
3.1.1
3.1.0
3.0.0
3.0.0-alpha.3
3.0.0-alpha.2
3.0.0-alpha.1
2.8.4
2.8.3
2.8.2
2.8.1
2.8.0
2.7.0
2.6.1
2.6.0
2.5.6
2.5.5
2.5.4
2.5.3
2.5.2
2.5.1
2.5.0
2.4.5
2.4.4
2.4.3
2.4.2
2.4.1
2.4.0
2.3.4
2.3.3
2.3.1
2.3.0
2.2.1
2.2.0
2.1.8
2.1.7
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.2
2.0.1
2.0.0
2.0.0-rc7
2.0.0-rc6
2.0.0-rc5
2.0.0-rc4
2.0.0-rc3
2.0.0-rc2
2.0.0-rc1
1.1.18
1.1.17
1.1.16
1.1.15
1.1.14
1.1.13
1.1.12
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
🌲 Great Elixir Logging Made Easy. Official Timber.io Integration.
Current section
Files
Jump to
Current section
Files
lib/timber/events/custom_event.ex
defmodule Timber.Events.CustomEvent do
@moduledoc ~S"""
The `CustomEvent` represents events that aren't covered elsewhere.
Custom events can be used to structure information about events that are central
to your line of business like receiving credit card payments, saving a draft of a post,
or changing a user's password.
## Fields
* `type` - (atom, required) This is the type of your event. It should be something unique
and unchanging. It will be used to identify this event. Example: `:my_event`.
* `data` - (map, optional) A map of data. This can be anything that can be JSON encoded.
Example: `%{key: "value"}`.
## Special `data` fields
Timber treats these fields as special. We'll display them on the interface where relevant,
create graphs, etc.:
* `:time_ms` (float, optional) - Represents the execution time in fractional milliseconds.
Example: `45.6`
## Example
There are 2 ways to log custom events:
1. Log a map (simplest)
```elixir
event_data = %{customer_id: "xiaus1934", amount: 1900, currency: "USD"}
Logger.info("Payment rejected", event: %{payment_rejected: event_data})
```
The `:payment_rejected` key is the event `type`, and of course the value is the `data`.
2. Log a struct (advanced)
Defining structs for your events creates a contract around your data structure.
We recommend this approach when you have downstream consumers that will be affected
by data structure changes.
```elixir
def PaymentRejectedEvent do
use Timber.Events.CustomEvent, type: :payment_rejected
@enforce_keys [:customer_id, :amount, :currency]
defstruct [:customer_id, :amount, :currency]
def message(%__MODULE__{customer_id: customer_id}) do
"Payment rejected for #{customer_id}"
end
end
event = %PaymentRejectedEvent{customer_id: "xiaus1934", amount: 1900, currency: "USD"}
message = PaymentRejectedEvent.message(event)
Logger.info(message, event: event)
```
"""
@type t :: %__MODULE__{
type: atom(),
data: map() | nil
}
defmacro __using__(opts) do
quote do
defimpl Timber.Eventable, for: __MODULE__ do
def to_event(event) do
type = Keyword.get(unquote(opts), :type, __MODULE__)
data = Map.from_struct(event)
%Timber.Events.CustomEvent{type: type, data: data}
end
end
end
end
@enforce_keys [:type]
defstruct [
:data,
:type
]
end