Skip to content

Commit 98925d2

Browse files
authored
Add retry mechanism (#18)
1 parent c47f410 commit 98925d2

20 files changed

+647
-751
lines changed

.tool-versions

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
elixir 1.16.0-otp-26
2+
erlang 26.2.1

CHANGELOG.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,44 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- Replaced `HTTPoison` library with `Tesla`.
13+
14+
### Removed
15+
16+
- Removed `Agent` strategy in favor of configuration. See `t:Segment.options/0` for configuration
17+
instructions.
18+
19+
### Added
20+
21+
- Retry mechanism for Segment API requests.
22+
- Request and response logs through `MetaLogger`.
23+
- Additional options available (see `t:Segment.options/0` for documentation):
24+
- `:disable_meta_logger`
25+
- `:filter_body`
26+
- `:http_adapter`
27+
- `:max_retries`
28+
- `:request_timeout`
29+
- `:retry_base_delay`
30+
- `:retry_jitter_factor`
31+
- `:retry_max_delay`
32+
1033
## [1.3.1] - 2022-03-17
1134

12-
## Changed
35+
### Changed
1336

1437
- Update the `miss` library.
1538

1639
## [1.3.0] - 2022-03-16
1740

18-
## Changed
41+
### Changed
1942

2043
- Fix the encoding for Decimal, Date and DateTime structs.
2144

2245
## [1.2.1] - 2022-02-25
2346

24-
## Changed
47+
### Changed
2548

2649
- Bump Poison to v5.0.
2750

README.md

Lines changed: 54 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,47 @@
1-
analytics-elixir ![analytics-elixir](https://github.com/FindHotel/analytics-elixir/workflows/analytics-elixir/badge.svg?branch=master)
2-
================
1+
# analytics-elixir ![analytics-elixir](https://github.com/FindHotel/analytics-elixir/workflows/analytics-elixir/badge.svg?branch=master)
32

43
analytics-elixir is a non-supported third-party client for [Segment](https://segment.com)
54

6-
## Install
5+
## Installation
76

8-
Add the following to deps section of your mix.exs: `{:segment, github: "FindHotel/analytics-elixir"}`
7+
Add the following to deps section of your mix.exs:
98

10-
and then `mix deps.get`
9+
```elixir
10+
{:segment, github: "FindHotel/analytics-elixir"}
11+
```
1112

12-
## Usage
13+
And then run:
1314

14-
Start the Segment agent with your write_key from Segment, and the endpoint.
15-
The __endpoint__ is optional and if omitted, it defaults to `https://api.segment.io/v1/`.
16-
```
17-
Segment.start_link("YOUR_SEGMENT_KEY", "https://example.com/v1")
15+
```sh
16+
mix deps.get
1817
```
19-
There are then two ways to call the different methods on the API.
20-
A basic way through `Segment.Analytics` or by passing a full Struct
21-
with all the data for the API (allowing Context and Integrations to be set)
2218

23-
## Usage in Phoenix
24-
25-
This is how I add to a Phoenix project (may not be your preferred way)
19+
## Usage
2620

27-
1. Add the following to deps section of your mix.exs: `{:segment, github: "FindHotel/analytics-elixir"}`
28-
and then `mix deps.get`
21+
For general usage, first define the `:key` configuration:
2922

30-
2. Add segment to applications list in the Phoenix project mix.exs
31-
ie.
32-
```
33-
def application do
34-
[mod: {FormAndThread, []},
35-
applications: [:phoenix, :phoenix_html, :cowboy, :logger,
36-
:phoenix_ecto, :postgrex, :segment]]
37-
end
23+
```elixir
24+
config :segment, key: "your_segment_key"
3825
```
3926

40-
3. Add a config variable for your write_key (may want to make this environment dependent)
41-
ie.
42-
```
43-
config :segment,
44-
key: "your_segment_key",
45-
endpoint: "https://api.segment.io/v1/"
46-
```
47-
The __endpoint__ is optional (as specified in the Usage section above).
27+
> For detailed information about configuration, see `t:Segment.options/0`.
4828
49-
4. Start the segment agent as a child of the application in the application file under
50-
the lib directory. In the children list add:
51-
```
52-
{Segment, [Application.get_env(:segment, :key), Application.get_env(:segment, :endpoint)]}
53-
```
29+
Then call `Segment.Analytics` functions to send analytics.
30+
31+
There are then two ways to call the functions:
32+
33+
- By using a collection of parameters
34+
- By using the related struct as a parameter
5435

5536
### Track
56-
```
37+
38+
```elixir
5739
Segment.Analytics.track(user_id, event, %{property1: "", property2: ""})
5840
```
41+
5942
or the full way using a struct with all the possible options for the track call
60-
```
43+
44+
```elixir
6145
%Segment.Analytics.Track{ userId: "sdsds",
6246
event: "eventname",
6347
properties: %{property1: "", property2: ""}
@@ -66,90 +50,86 @@ or the full way using a struct with all the possible options for the track call
6650
```
6751

6852
### Identify
69-
```
53+
54+
```elixir
7055
Segment.Analytics.identify(user_id, %{trait1: "", trait2: ""})
7156
```
57+
7258
or the full way using a struct with all the possible options for the identify call
73-
```
59+
60+
```elixir
7461
%Segment.Analytics.Identify{ userId: "sdsds",
7562
traits: %{trait1: "", trait2: ""}
7663
}
7764
|> Segment.Analytics.identify
7865
```
7966

8067
### Screen
81-
```
68+
69+
```elixir
8270
Segment.Analytics.screen(user_id, name)
8371
```
72+
8473
or the full way using a struct with all the possible options for the screen call
85-
```
74+
75+
```elixir
8676
%Segment.Analytics.Screen{ userId: "sdsds",
8777
name: "dssd"
8878
}
8979
|> Segment.Analytics.screen
9080
```
9181

9282
### Alias
93-
```
83+
84+
```elixir
9485
Segment.Analytics.alias(user_id, previous_id)
9586
```
87+
9688
or the full way using a struct with all the possible options for the alias call
97-
```
89+
90+
```elixir
9891
%Segment.Analytics.Alias{ userId: "sdsds",
9992
previousId: "dssd"
10093
}
10194
|> Segment.Analytics.alias
10295
```
10396

10497
### Group
105-
```
98+
99+
```elixir
106100
Segment.Analytics.group(user_id, group_id)
107101
```
102+
108103
or the full way using a struct with all the possible options for the group call
109-
```
104+
105+
```elixir
110106
%Segment.Analytics.Group{ userId: "sdsds",
111107
groupId: "dssd"
112108
}
113109
|> Segment.Analytics.group
114110
```
115111

116112
### Page
117-
```
113+
114+
```elixir
118115
Segment.Analytics.page(user_id, name)
119116
```
117+
120118
or the full way using a struct with all the possible options for the page call
121-
```
119+
120+
```elixir
122121
%Segment.Analytics.Page{ userId: "sdsds",
123122
name: "dssd"
124123
}
125124
|> Segment.Analytics.page
126125
```
127126

128-
### Config as options
127+
## Testing
129128

130-
You can also pass the __endpoint__ and __key__ as options to the
131-
`Segment.Analytics.call/2` along with the struct.
132-
```
133-
%Segment.Analytics.Track{ userId: "sdsds",
134-
event: "eventname",
135-
properties: %{property1: "", property2: ""}
136-
}
137-
|> Segment.Analytics.call([key: "YOUR_SEGMENT_KEY", endpoint: "https://example.com/v1"])
138-
```
129+
Clone the repository and run:
139130

140-
With this approach the options take precedence over configurations stored in the Segment agent.
141-
142-
### Filtering null JSON attributes from request body
143-
144-
You can avoid sending `null` JSON attributes to the configured Segment API endpoint by passing
145-
`drop_nil_fields: true` to the `Segment.Analytics.call/2` function.
146-
147-
## Running tests
148-
149-
There are not many tests at the moment. But you can run a live test on your segment
150-
account by running.
151-
```
152-
SEGMENT_KEY=yourkey mix test
131+
```sh
132+
mix test
153133
```
154134

155135
## Release

config/config.exs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,3 @@
1-
# This file is responsible for configuring your application
2-
# and its dependencies with the aid of the Mix.Config module.
3-
use Mix.Config
1+
import Config
42

5-
# This configuration is loaded before any dependency and is restricted
6-
# to this project. If another project depends on this project, this
7-
# file won't be loaded nor affect the parent project. For this reason,
8-
# if you want to provide default values for your application for third-
9-
# party users, it should be done in your mix.exs file.
10-
11-
# Sample configuration:
12-
#
13-
# config :logger, :console,
14-
# level: :info,
15-
# format: "$date $time [$level] $metadata$message\n",
16-
# metadata: [:user_id]
17-
18-
# It is also possible to import configuration files, relative to this
19-
# directory. For example, you can emulate configuration per environment
20-
# by uncommenting the line below and defining dev.exs, test.exs and such.
21-
# Configuration from the imported file will override the ones defined
22-
# here (which is why it is important to import them last).
23-
#
24-
# import_config "#{Mix.env}.exs"
3+
config :segment, http_adapter: Tesla.Mock, key: "my-amazing-key"

0 commit comments

Comments
 (0)