Skip to content

Commit 9600553

Browse files
authored
Add new_relic support
2 parents f75f016 + 8a32c61 commit 9600553

File tree

16 files changed

+312
-115
lines changed

16 files changed

+312
-115
lines changed

.circleci/config.yml

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
1-
version: 2
1+
version: 2.1
2+
23
jobs:
34
build:
45
docker:
56
- image: elixir:1.8.2-alpine
6-
name: app
7+
name: app
78
environment:
8-
MIX_ENV: test
9-
DATABASE_USER: user
10-
DATABASE_PASSWORD: pass
11-
DATABASE_PORT: 5432
12-
DATABASE_HOST: db
13-
DATABASE_NAME: ecto_job_scheduler_test
14-
DATABASE_POOL_SIZE: 5
15-
depends_on:
16-
- db
9+
MIX_ENV: test
10+
DATABASE_USER: user
11+
DATABASE_PASSWORD: pass
12+
DATABASE_PORT: "5432"
13+
DATABASE_HOST: db
14+
DATABASE_NAME: ecto_job_scheduler_test
15+
DATABASE_POOL_SIZE: "5"
1716
- image: postgres:9.6-alpine
1817
name: db
1918
environment:
2019
POSTGRES_USER: user
2120
POSTGRES_PASSWORD: pass
2221
POSTGRES_DB: ecto_job_scheduler_test
23-
22+
2423
working_directory: ~/app
2524

2625
steps:
@@ -29,20 +28,31 @@ jobs:
2928
- run: mix do deps.get, compile --warnings-as-errors
3029
- run: mix format --check-formatted
3130
- run: mix credo --strict
31+
- run: sh -c 'while true; do nc -z db 5432; if [[ "$?" == 0 ]]; then break; fi; sleep 1; done'
3232
- run: mix do ecto.create, ecto.migrate
3333
- run: mix coveralls.html
34+
- restore_cache:
35+
keys:
36+
- plt-cache-{{ checksum "mix.lock" }}-{{ .Branch }}
37+
- plt-cache-{{ checksum "mix.lock" }}
3438
- run: MIX_ENV=dev mix dialyzer --plt
39+
- save_cache:
40+
key: plt-cache-{{ checksum "mix.lock" }}-{{ .Branch }}
41+
paths:
42+
- _dialyzer/ecto-job-scheduler.plt
43+
- save_cache:
44+
key: plt-cache-{{ checksum "mix.lock" }}
45+
paths:
46+
- _dialyzer/ecto-job-scheduler.plt
47+
- run: MIX_ENV=dev mix dialyzer --format short
3548
- store_artifacts:
3649
path: cover/
37-
38-
50+
3951
workflows:
4052
version: 2
4153
build-and-deploy:
4254
jobs:
4355
- build:
4456
filters:
45-
branches:
46-
only: /.*/
4757
tags:
4858
only: /.*/

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,4 @@ ecto_job_scheduler-*.tar
2424
.elixir_ls/*
2525

2626
# Dialyzer
27-
/priv/plts/*.plt
28-
/priv/plts/*.plt.hash
27+
_dialyzer/*

CHANGELOG.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
11
# Changelog
2+
23
All notable changes to this project will be documented in this file.
34

45
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
56
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
67

78
## [Unreleased]
89

10+
## [1.1.0]
11+
12+
## Added
13+
14+
- Support for new_relic instrumentation for the jobs
15+
916
## [1.0.2] - 2020-02-18
1017

11-
### Fixes
18+
### Fixes
1219

1320
- Perform result
1421

1522
## [1.0.1] - 2020-02-11
1623

17-
### Fixes
24+
### Fixes
1825

1926
- Allow MFA tuple to be given sanitizer config
2027

2128
## [1.0.0] - 2020-01-22
2229

23-
### Added
30+
### Added
2431

2532
- Added support for ecto_job 3
2633

27-
[Unreleased]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.0.2...HEAD
34+
[Unreleased]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.1.0...HEAD
35+
[1.1.0]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.0.2...1.1.0
2836
[1.0.2]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.0.1...v1.0.2
2937
[1.0.1]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.0.0...v1.0.1
30-
[1.0.0]: https://github.com/rai200890/ecto-job-scheduler/compare/v0.7.0...v1.0.0
38+
[1.0.0]: https://github.com/rai200890/ecto-job-scheduler/compare/v0.7.0...v1.0.0

README.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
Helpers for scheduling Jobs defined in [EctoJob](https://github.com/mbuhot/ecto_job)
88

9-
Thanks [joaothallis](https://github.com/joaothallis), [ramondelemos](https://github.com/ramondelemos), [victorprs](https://github.com/victorprs)
9+
Thanks [joaothallis](https://github.com/joaothallis), [ramondelemos](https://github.com/ramondelemos), [victorprs](https://github.com/victorprs)
1010

1111
## Installation
1212

@@ -59,6 +59,20 @@ defmodule MyApplication.MyJobQueue do
5959
end
6060
```
6161

62+
If you want new_relic instrumentation in your jobs, add new_relic_agent to the deps and
63+
64+
```elixir
65+
defmodule MyApplication.MyJobQueue do
66+
@moduledoc false
67+
use EctoJobScheduler.JobQueue,
68+
table_name: "test_jobs",
69+
jobs: [
70+
MyApplication.MyJob
71+
],
72+
instrumenter: :new_relic
73+
end
74+
```
75+
6276
### Define scheduler module for job queue
6377

6478
```elixir
@@ -92,4 +106,4 @@ config :my_application, MyApplication.MyJob, max_attempts: "15"
92106
multi = Multi.run(:do_my_thing, fn _repo, _changes -> {:ok, :xablau} end)
93107
multi = MyJobScheduler.schedule(multi, MyJob, %{"input" => "a"})
94108
result = MyJobScheduler.run(multi)
95-
```
109+
```

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.4
1+
1.1.0

config/test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ end
2121
config :ecto_job_scheduler, sanitizer: sanitize_fun
2222

2323
config :logger, level: :warn
24+
25+
config :ecto_job_scheduler, EctoJobScheduler.NewRelic.JobInstrumenter,
26+
transaction: TransactionMock,
27+
reporter: ReporterMock

lib/job_queue.ex

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,44 @@ defmodule EctoJobScheduler.JobQueue do
33
Defines EctoJob.JobQueue based on defined EctoJobScheduler.Job
44
"""
55

6+
# credo:disable-for-this-file Credo.Check.Refactor.Nesting
7+
68
defmacro __using__(options \\ []) do
79
table_name = options[:table_name]
810
jobs = options[:jobs]
11+
instrumenter = options[:instrumenter]
912

10-
quote bind_quoted: [table_name: table_name, jobs: jobs] do
13+
quote bind_quoted: [table_name: table_name, jobs: jobs, instrumenter: instrumenter],
14+
location: :keep do
1115
use EctoJob.JobQueue, table_name: table_name
1216
require Logger
1317

1418
alias Ecto.Multi
19+
alias EctoJobScheduler.NewRelic.JobInstrumenter
1520

1621
Enum.each(jobs, fn job ->
1722
type = job |> Atom.to_string() |> String.split(".") |> List.last()
1823

19-
def perform(%Multi{} = multi, %{"type" => unquote(type)} = job_params) do
20-
apply(unquote(job), :perform, [multi, job_params])
24+
case instrumenter do
25+
:new_relic ->
26+
def perform(%Multi{} = multi, %{"type" => unquote(type)} = job_params) do
27+
case job_params["request_id"] do
28+
nil ->
29+
nil
30+
31+
request_id ->
32+
Logger.metadata(request_id: request_id)
33+
end
34+
35+
JobInstrumenter.transaction("job/#{unquote(type)}", fn ->
36+
apply(unquote(job), :perform, [multi, job_params])
37+
end)
38+
end
39+
40+
_ ->
41+
def perform(%Multi{} = multi, %{"type" => unquote(type)} = job_params) do
42+
apply(unquote(job), :perform, [multi, job_params])
43+
end
2144
end
2245
end)
2346
end

lib/new_relic/job_instrumenter.ex

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
defmodule EctoJobScheduler.NewRelic.JobInstrumenter do
2+
@moduledoc """
3+
Tool for capture metrics to NewRelic.
4+
"""
5+
6+
@doc """
7+
Execute a function and capture metrics to NewRelic from it.
8+
The metrics is grouped with name parameter.
9+
10+
Example of use:
11+
12+
NewRelic.JobInstrumenter.transaction("job/1", fn ->
13+
...
14+
end)
15+
"""
16+
@spec transaction(
17+
name :: String.t(),
18+
function :: (() -> {:error, term()} | any() | no_return())
19+
) ::
20+
term()
21+
def transaction(name, function) do
22+
start()
23+
24+
add_attributes(
25+
other_transaction_name: name,
26+
request_id: get_request_id()
27+
)
28+
29+
case function.() do
30+
{:error, reason} ->
31+
{:current_stacktrace, stack} = Process.info(self(), :current_stacktrace)
32+
fail(:error, reason, stack)
33+
complete()
34+
{:error, reason}
35+
36+
result ->
37+
complete()
38+
result
39+
end
40+
rescue
41+
exception ->
42+
fail(exception.__struct__, Exception.message(exception), __STACKTRACE__)
43+
complete()
44+
reraise exception, __STACKTRACE__
45+
end
46+
47+
defp start do
48+
reporter().start()
49+
end
50+
51+
defp add_attributes(attributes) do
52+
reporter().add_attributes(attributes)
53+
end
54+
55+
defp fail(kind, reason, stack) do
56+
reporter().fail(self(), %{
57+
kind: kind,
58+
reason: reason,
59+
stack: stack
60+
})
61+
end
62+
63+
defp complete do
64+
transaction().stop_transaction()
65+
end
66+
67+
defp get_request_id do
68+
Keyword.get(Logger.metadata(), :request_id)
69+
end
70+
71+
defp reporter,
72+
do:
73+
Application.get_env(:ecto_job_scheduler, __MODULE__)[:reporter] ||
74+
NewRelic.Transaction.Reporter
75+
76+
defp transaction,
77+
do: Application.get_env(:ecto_job_scheduler, __MODULE__)[:transaction] || NewRelic.Transaction
78+
end

lib/new_relic/reporter.ex

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
defmodule EctoJobScheduler.NewRelic.Reporter do
2+
@moduledoc false
3+
4+
@callback start() :: term()
5+
6+
@callback add_attributes(keyword()) :: term()
7+
8+
@callback fail(pid(), map()) :: term()
9+
10+
@callback complete(pid(), atom()) :: term()
11+
end

lib/new_relic/transaction.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
defmodule EctoJobScheduler.NewRelic.TransactionBehaviour do
2+
@moduledoc false
3+
4+
@callback stop_transaction() :: :ok
5+
end

0 commit comments

Comments
 (0)