Skip to content

Commit

Permalink
Add new_relic support
Browse files Browse the repository at this point in the history
  • Loading branch information
VitorTrin authored Jun 17, 2020
2 parents f75f016 + 8a32c61 commit 9600553
Show file tree
Hide file tree
Showing 16 changed files with 312 additions and 115 deletions.
42 changes: 26 additions & 16 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
version: 2
version: 2.1

jobs:
build:
docker:
- image: elixir:1.8.2-alpine
name: app
name: app
environment:
MIX_ENV: test
DATABASE_USER: user
DATABASE_PASSWORD: pass
DATABASE_PORT: 5432
DATABASE_HOST: db
DATABASE_NAME: ecto_job_scheduler_test
DATABASE_POOL_SIZE: 5
depends_on:
- db
MIX_ENV: test
DATABASE_USER: user
DATABASE_PASSWORD: pass
DATABASE_PORT: "5432"
DATABASE_HOST: db
DATABASE_NAME: ecto_job_scheduler_test
DATABASE_POOL_SIZE: "5"
- image: postgres:9.6-alpine
name: db
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: ecto_job_scheduler_test

working_directory: ~/app

steps:
Expand All @@ -29,20 +28,31 @@ jobs:
- run: mix do deps.get, compile --warnings-as-errors
- run: mix format --check-formatted
- run: mix credo --strict
- run: sh -c 'while true; do nc -z db 5432; if [[ "$?" == 0 ]]; then break; fi; sleep 1; done'
- run: mix do ecto.create, ecto.migrate
- run: mix coveralls.html
- restore_cache:
keys:
- plt-cache-{{ checksum "mix.lock" }}-{{ .Branch }}
- plt-cache-{{ checksum "mix.lock" }}
- run: MIX_ENV=dev mix dialyzer --plt
- save_cache:
key: plt-cache-{{ checksum "mix.lock" }}-{{ .Branch }}
paths:
- _dialyzer/ecto-job-scheduler.plt
- save_cache:
key: plt-cache-{{ checksum "mix.lock" }}
paths:
- _dialyzer/ecto-job-scheduler.plt
- run: MIX_ENV=dev mix dialyzer --format short
- store_artifacts:
path: cover/



workflows:
version: 2
build-and-deploy:
jobs:
- build:
filters:
branches:
only: /.*/
tags:
only: /.*/
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,4 @@ ecto_job_scheduler-*.tar
.elixir_ls/*

# Dialyzer
/priv/plts/*.plt
/priv/plts/*.plt.hash
_dialyzer/*
18 changes: 13 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
# Changelog

All notable changes to this project will be documented in this file.

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

## [Unreleased]

## [1.1.0]

## Added

- Support for new_relic instrumentation for the jobs

## [1.0.2] - 2020-02-18

### Fixes
### Fixes

- Perform result

## [1.0.1] - 2020-02-11

### Fixes
### Fixes

- Allow MFA tuple to be given sanitizer config

## [1.0.0] - 2020-01-22

### Added
### Added

- Added support for ecto_job 3

[Unreleased]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.0.2...HEAD
[Unreleased]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.1.0...HEAD
[1.1.0]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.0.2...1.1.0
[1.0.2]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.0.1...v1.0.2
[1.0.1]: https://github.com/rai200890/ecto-job-scheduler/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/rai200890/ecto-job-scheduler/compare/v0.7.0...v1.0.0
[1.0.0]: https://github.com/rai200890/ecto-job-scheduler/compare/v0.7.0...v1.0.0
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

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

Thanks [joaothallis](https://github.com/joaothallis), [ramondelemos](https://github.com/ramondelemos), [victorprs](https://github.com/victorprs)
Thanks [joaothallis](https://github.com/joaothallis), [ramondelemos](https://github.com/ramondelemos), [victorprs](https://github.com/victorprs)

## Installation

Expand Down Expand Up @@ -59,6 +59,20 @@ defmodule MyApplication.MyJobQueue do
end
```

If you want new_relic instrumentation in your jobs, add new_relic_agent to the deps and

```elixir
defmodule MyApplication.MyJobQueue do
@moduledoc false
use EctoJobScheduler.JobQueue,
table_name: "test_jobs",
jobs: [
MyApplication.MyJob
],
instrumenter: :new_relic
end
```

### Define scheduler module for job queue

```elixir
Expand Down Expand Up @@ -92,4 +106,4 @@ config :my_application, MyApplication.MyJob, max_attempts: "15"
multi = Multi.run(:do_my_thing, fn _repo, _changes -> {:ok, :xablau} end)
multi = MyJobScheduler.schedule(multi, MyJob, %{"input" => "a"})
result = MyJobScheduler.run(multi)
```
```
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.4
1.1.0
4 changes: 4 additions & 0 deletions config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ end
config :ecto_job_scheduler, sanitizer: sanitize_fun

config :logger, level: :warn

config :ecto_job_scheduler, EctoJobScheduler.NewRelic.JobInstrumenter,
transaction: TransactionMock,
reporter: ReporterMock
29 changes: 26 additions & 3 deletions lib/job_queue.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,44 @@ defmodule EctoJobScheduler.JobQueue do
Defines EctoJob.JobQueue based on defined EctoJobScheduler.Job
"""

# credo:disable-for-this-file Credo.Check.Refactor.Nesting

defmacro __using__(options \\ []) do
table_name = options[:table_name]
jobs = options[:jobs]
instrumenter = options[:instrumenter]

quote bind_quoted: [table_name: table_name, jobs: jobs] do
quote bind_quoted: [table_name: table_name, jobs: jobs, instrumenter: instrumenter],
location: :keep do
use EctoJob.JobQueue, table_name: table_name
require Logger

alias Ecto.Multi
alias EctoJobScheduler.NewRelic.JobInstrumenter

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

def perform(%Multi{} = multi, %{"type" => unquote(type)} = job_params) do
apply(unquote(job), :perform, [multi, job_params])
case instrumenter do
:new_relic ->
def perform(%Multi{} = multi, %{"type" => unquote(type)} = job_params) do
case job_params["request_id"] do
nil ->
nil

request_id ->
Logger.metadata(request_id: request_id)
end

JobInstrumenter.transaction("job/#{unquote(type)}", fn ->
apply(unquote(job), :perform, [multi, job_params])
end)
end

_ ->
def perform(%Multi{} = multi, %{"type" => unquote(type)} = job_params) do
apply(unquote(job), :perform, [multi, job_params])
end
end
end)
end
Expand Down
78 changes: 78 additions & 0 deletions lib/new_relic/job_instrumenter.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
defmodule EctoJobScheduler.NewRelic.JobInstrumenter do
@moduledoc """
Tool for capture metrics to NewRelic.
"""

@doc """
Execute a function and capture metrics to NewRelic from it.
The metrics is grouped with name parameter.
Example of use:
NewRelic.JobInstrumenter.transaction("job/1", fn ->
...
end)
"""
@spec transaction(
name :: String.t(),
function :: (() -> {:error, term()} | any() | no_return())
) ::
term()
def transaction(name, function) do
start()

add_attributes(
other_transaction_name: name,
request_id: get_request_id()
)

case function.() do
{:error, reason} ->
{:current_stacktrace, stack} = Process.info(self(), :current_stacktrace)
fail(:error, reason, stack)
complete()
{:error, reason}

result ->
complete()
result
end
rescue
exception ->
fail(exception.__struct__, Exception.message(exception), __STACKTRACE__)
complete()
reraise exception, __STACKTRACE__
end

defp start do
reporter().start()
end

defp add_attributes(attributes) do
reporter().add_attributes(attributes)
end

defp fail(kind, reason, stack) do
reporter().fail(self(), %{
kind: kind,
reason: reason,
stack: stack
})
end

defp complete do
transaction().stop_transaction()
end

defp get_request_id do
Keyword.get(Logger.metadata(), :request_id)
end

defp reporter,
do:
Application.get_env(:ecto_job_scheduler, __MODULE__)[:reporter] ||
NewRelic.Transaction.Reporter

defp transaction,
do: Application.get_env(:ecto_job_scheduler, __MODULE__)[:transaction] || NewRelic.Transaction
end
11 changes: 11 additions & 0 deletions lib/new_relic/reporter.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule EctoJobScheduler.NewRelic.Reporter do
@moduledoc false

@callback start() :: term()

@callback add_attributes(keyword()) :: term()

@callback fail(pid(), map()) :: term()

@callback complete(pid(), atom()) :: term()
end
5 changes: 5 additions & 0 deletions lib/new_relic/transaction.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule EctoJobScheduler.NewRelic.TransactionBehaviour do
@moduledoc false

@callback stop_transaction() :: :ok
end
9 changes: 6 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule EctoJobScheduler.MixProject do
extras: ["README.md"]
],
dialyzer: [
plt_file: {:no_warn, "priv/plts/dialyzer.plt"},
plt_file: {:no_warn, "_dialyzer/ecto-job-scheduler.plt"},
remove_defaults: [:unknown]
]
]
Expand Down Expand Up @@ -56,10 +56,13 @@ defmodule EctoJobScheduler.MixProject do
defp deps do
[
{:ecto_job, "~> 3.0"},
{:credo, "~> 1.1", only: [:dev, :test], runtime: false},
{:ecto_sql, "~> 3.4"},
{:credo, "~> 1.4", only: [:dev, :test], runtime: false},
{:excoveralls, "~> 0.10", only: :test},
{:ex_doc, "~> 0.14", only: :dev, runtime: false},
{:dialyxir, "~> 1.0", only: [:dev], runtime: false}
{:dialyxir, "~> 1.0", only: [:dev], runtime: false},
{:new_relic_agent, "~> 1.19", optional: true},
{:mox, "~> 0.5", only: [:dev, :test], runtime: false}
]
end
end
Loading

0 comments on commit 9600553

Please sign in to comment.