datadog-json_logger 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46efa4917f2fc960dac808402a47fe0f05bb3b7f99fbe110025bd8242450b44c
4
- data.tar.gz: 70a463c19df71d259095a002e93a2d078a4cd042720a8ee271ff18326bd903ad
3
+ metadata.gz: 9df47f5fde7ef4639bbba0854c2d9fa90db7f580d489bfc04051c79c191c7d8f
4
+ data.tar.gz: 8f88db7cf3f19787fabb34d4fa95d787689223e8e933a9e38f3f448b2501322b
5
5
  SHA512:
6
- metadata.gz: b76fb7fb03ecb2ef77fe8bcda47a231addb9c87705cd31c97f3f06ac5cdd74c85751ea5d23e7dc114ae59e3b0a4ac062f5501154f2dc7e987fef0fc6c0c6e960
7
- data.tar.gz: 6b3ee3641cd0615e7a3ab8b5bcc3136eeed303c492ae95c7d5448f7d03a32e7818b231afe8ef39bdfee0814bf1d8ac87cd0eaed93671f038166971e4a8efcb36
6
+ metadata.gz: 24e9e6f6a59711c62bcc386be834a0b2e98bdc70e53084c7da73a6b04a26f25b091afae4a61b8049b6e24b5bc94901997b3383b8fa1d485033f09919140b5ac9
7
+ data.tar.gz: 8ad6344f4e503a946f6653a30840b9dca8afc70e161b5369a582dbcd2105b276f3545c66d396fb60ac6d25725745a6322c607336931a542f34915a3234652889
data/.rubocop.yml CHANGED
@@ -2,6 +2,7 @@ AllCops:
2
2
  Exclude:
3
3
  - 'sig/**/*'
4
4
  - 'datadog-json_logger.gemspec'
5
+ - 'lib/datadog/tracing/contrib/bunny/patcher.rb'
5
6
  - 'vendor/**/*'
6
7
  NewCops: enable
7
8
  TargetRubyVersion: 3.0
data/README.md CHANGED
@@ -4,27 +4,40 @@
4
4
  [![Rubocop and Rspec](https://github.com/buyco/datadog-json-logger/actions/workflows/main.yml/badge.svg)](https://github.com/buyco/datadog-json-logger/actions/workflows/main.yml)
5
5
  [![Publish on RubyGems](https://github.com/buyco/datadog-json-logger/actions/workflows/gem-push.yml/badge.svg)](https://github.com/buyco/datadog-json-logger/actions/workflows/gem-push.yml)
6
6
 
7
- `Datadog::JSONLogger` is a Ruby gem designed to seamlessly integrate Ruby applications with Datadog's logging and tracing services. This gem allows your Ruby application to format its output as JSON, including necessary correlation IDs and other details for optimal Datadog functionality.
7
+ ## Overview
8
8
 
9
- ## Prerequisites
9
+ `Datadog::JSONLogger` is a Ruby gem that provides seamless integration with Datadog's logging and tracing services. It formats logs as JSON with correlation IDs, making it easy to integrate with Datadog's log management and APM services.
10
10
 
11
- Before you begin, ensure you have [ddtrace](https://github.com/DataDog/dd-trace-rb) configured in your Ruby application, as `Datadog::JSONLogger` relies on `ddtrace` for tracing data.
11
+ ## Features
12
+
13
+ | Feature | Description | Status |
14
+ |-------------------------|-------------|---------|
15
+ | JSON correlated logging | Formats logs as JSON with Datadog correlation IDs for better log analysis | ✅ |
16
+ | Tracing | Integrates with Datadog APM for distributed tracing | ✅ |
17
+ | Error Tracking | Compatible with Datadog error tracking | ✅ |
18
+ | Rack Middleware | Provides a Rack middleware for HTTP request logging | ✅ |
19
+ | Bunny Integration | Adds tracing for RabbitMQ operations via Bunny | ✅ |
20
+
21
+ ## Requirements
22
+
23
+ - Ruby 3.0+
24
+ - [ddtrace](https://github.com/DataDog/dd-trace-rb) properly configured in your application
12
25
 
13
26
  ## Installation
14
27
 
15
- Add this line to your application's Gemfile:
28
+ Add to your application's Gemfile:
16
29
 
17
30
  ```ruby
18
31
  gem 'datadog-json_logger'
19
32
  ```
20
33
 
21
- And then execute:
34
+ And run:
22
35
 
23
36
  ```bash
24
37
  bundle install
25
38
  ```
26
39
 
27
- Or install it yourself as:
40
+ Or install it directly:
28
41
 
29
42
  ```bash
30
43
  gem install datadog-json_logger
@@ -32,78 +45,178 @@ gem install datadog-json_logger
32
45
 
33
46
  ## Usage
34
47
 
35
- ### JSONLogger
36
-
37
- `Datadog::JSONLogger` can be easily integrated into your Ruby application. Here's a quick example of how to use it in a Sinatra application:
48
+ ### Basic JSON Logger
38
49
 
39
50
  ```ruby
40
- # Example in Sinatra (app.rb)
41
51
  require 'datadog/json_logger'
42
52
 
53
+ # Create a logger instance
54
+ logger = Datadog::JSONLogger.new
55
+ logger.info('Hello World')
56
+ # => {"dd":{"trace_id":"0","span_id":"0","env":null,"service":"console","version":null},"timestamp":"2023-11-22 22:28:00 +0100","severity":"INFO ","progname":"","message":"Hello World"}
57
+ ```
58
+
59
+ ### Configuration
60
+
61
+ ```ruby
43
62
  Datadog::JSONLogger.configure do |config|
44
- config.current_user = ->(env) { { email: env['warned'].user.email } } # Log user on each request
63
+ # Function to extract current user from environment
64
+ config.current_user = ->(env) { { email: env['current_user']&.email } }
65
+
66
+ # Custom environment keys
45
67
  config.controller_key = "sinatra.controller_name"
46
- config.resource_key = "sinatra.resource_name"
47
- config.action_key = "sinatra.action_name"
68
+ config.resource_key = "sinatra.resource_name"
69
+ config.action_key = "sinatra.action_name"
70
+
71
+ # Custom context for all logs
72
+ config.custom_context = -> { { environment: ENV['RACK_ENV'] } }
48
73
  end
74
+ ```
49
75
 
50
- def logger
51
- @logger ||= Datadog::JSONLogger.new
76
+ ### With Rails
77
+
78
+ In your `config/initializers/datadog.rb`:
79
+
80
+ ```ruby
81
+ require 'datadog/json_logger'
82
+
83
+ Datadog::JSONLogger.configure do |config|
84
+ config.current_user = ->(env) { { email: env['warden']&.user&.email } }
85
+ config.controller_key = "action_controller.instance"
86
+ config.action_key = "action_dispatch.request.path_parameters[:action]"
87
+ config.resource_key = "action_dispatch.request.path_parameters[:controller]"
52
88
  end
53
89
 
54
- set :logger, logger
90
+ # Configure Rails logger
91
+ Rails.application.config.logger = Datadog::JSONLogger.new
92
+ ```
93
+
94
+ ### With Sinatra
95
+
96
+ ```ruby
97
+ require 'datadog/json_logger'
98
+ require 'datadog/rack_middleware'
55
99
 
56
- Sinatra::Application.logger.info("hello")
57
- # => {"dd":{"trace_id":"0","span_id":"0","env":null,"service":"console","version":null},"timestamp":"2023-11-22 22:28:00 +0100","severity":"INFO ","progname":"","message":"hello"}
100
+ class MyApp < Sinatra::Base
101
+ configure do
102
+ # Configure Datadog logger
103
+ Datadog::JSONLogger.configure do |config|
104
+ config.current_user = ->(env) { { email: env['warden']&.user&.email } }
105
+ end
106
+
107
+ # Set up logger
108
+ set :logger, Datadog::JSONLogger.new
109
+
110
+ # Add Rack middleware
111
+ use Datadog::RackMiddleware, settings.logger
112
+ end
113
+
114
+ # Your routes here
115
+ end
58
116
  ```
59
117
 
60
- #### Add Custom Keys
61
- Create a custom formatter that inherits from `Datadog::Loggers::JSONFormatter` to add custom keys as shown below:
118
+ ### Custom Formatter
119
+
120
+ Create a custom formatter to add more fields to your logs:
62
121
 
63
122
  ```ruby
64
123
  class CustomFormatter < Datadog::Loggers::JSONFormatter
65
124
  def self.call(severity, datetime, progname, msg)
66
125
  super do |log_hash|
67
- log_hash[:my_custom_key] = "my_value"
68
- log_hash[:my_custom_hash] = { key: "value" }
126
+ log_hash[:app_name] = "my_application"
127
+ log_hash[:environment] = ENV['RACK_ENV']
128
+ log_hash[:custom_field] = "custom value"
69
129
  end
70
130
  end
71
131
  end
72
132
 
73
- def logger
74
- return @logger if @logger
75
-
76
- @logger = Datadog::JSONLogger.new
77
- @logger.progname = "my_app"
78
- @logger.formatter = CustomFormatter
79
- @logger
80
- end
81
-
82
- Sinatra::Application.logger.info("hello")
83
- # {"dd":{"trace_id":"0","span_id":"0","env":null,"service":"console","version":null},"timestamp":"2023-11-22 22:46:01 +0100","severity":"INFO ","progname":"my_app","message":"hello","my_custom_key":"my_value","my_custom_hash":{"key":"value"}}
133
+ # Use the custom formatter
134
+ logger = Datadog::JSONLogger.new
135
+ logger.formatter = CustomFormatter
84
136
  ```
85
137
 
86
- ### RackMiddleware
138
+ ### Rack Middleware
87
139
 
88
- `Datadog::RackMiddleware` formats Rack requests as JSON and disables the default textual stdout of `Rack::CommonLogger`:
140
+ The `Datadog::RackMiddleware` logs HTTP requests in a structured format and disables the default `Rack::CommonLogger` output:
89
141
 
90
142
  ```ruby
91
- # Example in Sinatra (app.rb)
92
143
  require 'datadog/rack_middleware'
93
144
 
145
+ # For Rack applications
94
146
  use Datadog::RackMiddleware, logger
95
147
 
96
- # Example in Rails (config.rb)
97
- config.middleware.use Datadog::RackMiddleware, config.logger
148
+ # For Rails
149
+ Rails.application.config.middleware.use Datadog::RackMiddleware, Rails.logger
98
150
  ```
99
151
 
100
- ## Features
101
- | Feature | Link | Compatibility |
102
- |-------------------------|-------------------------------------------------|---------------|
103
- | JSON correlated logging | [Ruby Collection](https://docs.datadoghq.com/logs/log_collection/ruby/?tab=lograge) | ✅ |
104
- | Tracing | [Ruby Tracing application](https://docs.datadoghq.com/tracing/trace_collection/dd_libraries/ruby) | ✅ |
105
- | Error Tracking | [Datadog error tracking](https://www.datadoghq.com/product/error-tracking) | ✅ |
152
+ Sample output:
153
+
154
+ ```json
155
+ {
156
+ "dd": {
157
+ "trace_id": "1234567890",
158
+ "span_id": "0987654321",
159
+ "env": "production",
160
+ "service": "my-service",
161
+ "version": "1.0.0"
162
+ },
163
+ "request": true,
164
+ "params": {"q": "search"},
165
+ "status": 200,
166
+ "format": "application/json",
167
+ "duration": 45,
168
+ "request_ip": "127.0.0.1",
169
+ "method": "GET",
170
+ "path": "/api/users",
171
+ "controller": "UsersController",
172
+ "action": "index",
173
+ "resource": "users",
174
+ "usr": {"email": "user@example.com"},
175
+ "message": "Received GET request from 127.0.0.1 at /api/users Responded with status 200 in 45ms."
176
+ }
177
+ ```
178
+
179
+ ### Bunny Integration
106
180
 
181
+ Trace RabbitMQ operations with the Bunny integration:
182
+
183
+ ```ruby
184
+ require 'datadog/json_logger'
185
+
186
+ # Configure Datadog tracing
187
+ Datadog.configure do |c|
188
+ c.tracing.instrument :bunny, service_name: 'rabbitmq-service'
189
+ # Other Datadog configurations...
190
+ end
191
+ ```
192
+
193
+ #### End-to-End Tracing for Bunny Consumers
194
+
195
+ For complete end-to-end tracing when consuming messages with Bunny, you need to manually continue the trace by using the helper in `lib/datadog/tracing/contrib/bunny/utils.rb`. Since the `on_delivery` method is a block, it's not possible to automatically retrieve trace information to continue the trace.
196
+
197
+ ```ruby
198
+ require 'datadog/tracing/contrib/bunny/utils'
199
+
200
+ # Use Bunny as normal
201
+ bunny = Bunny.new
202
+ bunny.start
203
+
204
+ channel = bunny.create_channel
205
+ queue = channel.queue("my_queue")
206
+
207
+ # Publishing (automatically traced)
208
+ channel.default_exchange.publish("Hello World!", routing_key: queue.name)
209
+
210
+ # Consuming (automatically traced)
211
+ queue.subscribe(block: true) do |delivery_info, properties, payload|
212
+ # Continue the trace from the producer
213
+ if properties.headers && properties.headers[:trace_digest]
214
+ Datadog::Tracing::Contrib::Bunny::Utils.continue_trace!(properties.headers[:trace_digest])
215
+ end
216
+
217
+ handle_message(payload)
218
+ end
219
+ ```
107
220
 
108
221
  ## Development
109
222
 
@@ -127,4 +240,4 @@ This gem is available as open source under the terms of the [MIT License](https:
127
240
 
128
241
  ## Code of Conduct
129
242
 
130
- Everyone interacting in the Datadog::JSONLogger project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/buyco/datadog-json-logger/blob/main/CODE_OF_CONDUCT.md).
243
+ Everyone interacting in the Datadog::JSONLogger project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/buyco/datadog-json-logger/blob/main/CODE_OF_CONDUCT.md).
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Datadog
4
4
  module Loggers
5
- VERSION = "0.2.2"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "datadog/tracing/contrib/configuration/settings"
4
+
5
+ module Datadog
6
+ module Tracing
7
+ module Contrib
8
+ module Bunny
9
+ module Configuration
10
+ # Configuration settings for Bunny
11
+ class Settings < Contrib::Configuration::Settings
12
+ option :service_name, default: "bunny"
13
+ option :analytics_enabled, default: false
14
+ option :analytics_sample_rate, default: 1.0
15
+ option :distributed_tracing, default: true
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module Bunny
7
+ # @public_api Changing resource names, tag names, or environment variables creates breaking changes.
8
+ module Ext
9
+ APP = "bunny"
10
+ ENV_ENABLED = "DD_TRACE_BUNNY_ENABLED"
11
+ ENV_SERVICE_NAME = "DD_TRACE_BUNNY_SERVICE_NAME"
12
+ ENV_ANALYTICS_ENABLED = "DD_TRACE_BUNNY_ANALYTICS_ENABLED"
13
+ ENV_ANALYTICS_SAMPLE_RATE = "DD_TRACE_BUNNY_ANALYTICS_SAMPLE_RATE"
14
+ SPAN_BASIC_PUBLISH = "bunny.publish"
15
+ SPAN_EXCHANGE_NAME = "bunny.exchange"
16
+ SPAN_EXCHANGE_PUBLISH = "bunny.exchange.publish"
17
+ SPAN_CONSUME = "bunny.consume"
18
+ SPAN_QUEUE_NAME = "bunny.queue"
19
+ SPAN_QUEUE_POP = "bunny.queue.pop"
20
+ SPAN_CHANNEL_ID = "bunny.channel.id"
21
+ TAG_MESSAGING_SYSTEM = "rabbitmq"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "datadog/tracing/contrib"
4
+ require "datadog/tracing/contrib/integration"
5
+ require "datadog/tracing/contrib/bunny/configuration/settings"
6
+ require "datadog/tracing/contrib/bunny/patcher"
7
+ require "datadog/tracing/contrib/bunny/utils"
8
+
9
+ module Datadog
10
+ module Tracing
11
+ module Contrib
12
+ module Bunny
13
+ class Integration
14
+ include Contrib::Integration
15
+
16
+ MINIMUM_VERSION = Gem::Version.new("2.0.0")
17
+
18
+ register_as :bunny
19
+
20
+ def self.gem_name
21
+ "bunny"
22
+ end
23
+
24
+ def self.version
25
+ Gem.loaded_specs["bunny"]&.version
26
+ end
27
+
28
+ def self.loaded?
29
+ !defined?(::Bunny).nil?
30
+ end
31
+
32
+ def self.compatible?
33
+ super && version && version >= MINIMUM_VERSION
34
+ end
35
+
36
+ def auto_instrument?
37
+ false
38
+ end
39
+
40
+ def new_configuration
41
+ Configuration::Settings.new
42
+ end
43
+
44
+ def patcher
45
+ Patcher
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "datadog/tracing/contrib/patcher"
4
+ require "datadog/tracing/contrib/bunny/ext"
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Bunny
10
+ # Patcher for Bunny instrumentation
11
+ module Patcher
12
+ include Contrib::Patcher
13
+
14
+ module_function
15
+
16
+ def target_version
17
+ Integration.version
18
+ end
19
+
20
+ def patch
21
+ ::Bunny::Channel.prepend(ChannelPatch)
22
+ ::Bunny::Exchange.prepend(ExchangePatch)
23
+ ::Bunny::Queue.prepend(QueuePatch)
24
+ ::Bunny::Consumer.prepend(ConsumerPatch)
25
+ end
26
+
27
+ # Patch for Bunny::Channel
28
+ module ChannelPatch
29
+ def basic_consume(queue, consumer_tag = generate_consumer_tag, no_ack = false, exclusive = false,
30
+ arguments = nil, &block)
31
+ config = Datadog.configuration.tracing[:bunny]
32
+ Datadog::Tracing.trace(Ext::SPAN_CONSUME, service: config.service_name) do |span|
33
+ span.type = Datadog::Tracing::Metadata::Ext::AppTypes::TYPE_WORKER
34
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, Ext::APP)
35
+ span.set_tag(Ext::SPAN_CHANNEL_ID, id)
36
+
37
+ super
38
+ end
39
+ end
40
+
41
+ def basic_publish(payload, exchange, routing_key, opts = {})
42
+ config = Datadog.configuration.tracing[:bunny]
43
+ Datadog::Tracing.trace(Ext::SPAN_BASIC_PUBLISH, service: config.service_name) do |span|
44
+ span.type = Datadog::Tracing::Metadata::Ext::AppTypes::TYPE_WORKER
45
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, Ext::APP)
46
+ span.set_tag(Ext::SPAN_CHANNEL_ID, id)
47
+
48
+ super
49
+ end
50
+ end
51
+ end
52
+
53
+ # Patch for Bunny::Exchange
54
+ module ExchangePatch
55
+ def publish(payload, opts = {})
56
+ config = Datadog.configuration.tracing[:bunny]
57
+ Datadog::Tracing.trace(Ext::SPAN_EXCHANGE_PUBLISH, service: config.service_name) do |span|
58
+ span.type = Datadog::Tracing::Metadata::Ext::AppTypes::TYPE_WORKER
59
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, Ext::APP)
60
+ span.set_tag(Ext::SPAN_EXCHANGE_NAME, name)
61
+
62
+ if (trace_digest = Datadog::Tracing.active_trace&.to_digest)
63
+ opts[:trace_digest] ||= {}
64
+ hash = JSON.parse(trace_digest.to_json)
65
+ opts[:trace_digest].merge!(hash)
66
+ end
67
+ super
68
+ end
69
+ end
70
+ end
71
+
72
+ # Patch for Bunny::Queue
73
+ module QueuePatch
74
+ def pop(opts = { manual_ack: false }, &block)
75
+ config = Datadog.configuration.tracing[:bunny]
76
+ Datadog::Tracing.trace(Ext::SPAN_QUEUE_POP, service: config.service_name) do |span|
77
+ span.type = Datadog::Tracing::Metadata::Ext::AppTypes::TYPE_WORKER
78
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, Ext::APP)
79
+ span.set_tag(Ext::SPAN_QUEUE_NAME, name)
80
+
81
+ super
82
+ end
83
+ end
84
+ end
85
+
86
+ # Patch for Bunny::Consumer
87
+ module ConsumerPatch
88
+ def on_delivery(&block)
89
+ config = Datadog.configuration.tracing[:bunny]
90
+ Datadog::Tracing.trace(Ext::SPAN_CONSUME, service: config.service_name) do |span|
91
+ span.type = Datadog::Tracing::Metadata::Ext::AppTypes::TYPE_WORKER
92
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, Ext::APP)
93
+
94
+ super
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module Bunny
7
+ module Utils
8
+ module_function
9
+
10
+ # @param metadata [Hash, String]
11
+ # @return [void]
12
+ def continue_trace!(metadata)
13
+ serializes_trace_digest = if metadata.is_a?(Hash)
14
+ metadata.transform_keys(&:to_sym)
15
+ elsif metadata.is_a?(String)
16
+ JSON.parse(metadata, symbolize_names: true)
17
+ else
18
+ return
19
+ end
20
+
21
+ trace_digest = Datadog::Tracing::TraceDigest.new(**serializes_trace_digest)
22
+ return unless trace_digest
23
+
24
+ Datadog::Tracing.continue_trace!(trace_digest)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ # Datadog::Tracing::Contrib::Bunny::Utils.continue_trace!(metadata)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datadog-json_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eth3rnit3
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-10 00:00:00.000000000 Z
11
+ date: 2025-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: datadog
@@ -49,6 +49,11 @@ files:
49
49
  - lib/datadog/loggers/json_formatter.rb
50
50
  - lib/datadog/loggers/version.rb
51
51
  - lib/datadog/rack_middleware.rb
52
+ - lib/datadog/tracing/contrib/bunny/configuration/settings.rb
53
+ - lib/datadog/tracing/contrib/bunny/ext.rb
54
+ - lib/datadog/tracing/contrib/bunny/integration.rb
55
+ - lib/datadog/tracing/contrib/bunny/patcher.rb
56
+ - lib/datadog/tracing/contrib/bunny/utils.rb
52
57
  - nexus_release.sh
53
58
  - sig/.keep
54
59
  homepage: https://github.com/buyco/datadog-json-logger