Skip to content

Commit

Permalink
Merge pull request #2087 from newrelic/set_log_attributes_via_config
Browse files Browse the repository at this point in the history
Set custom log attributes using newrelic.yml or environment variables
  • Loading branch information
kaylareopelle authored Jun 20, 2023
2 parents 140ea80 + 7815360 commit 1fca78c
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 6 deletions.
19 changes: 13 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## dev

Version <dev> of the agent adds log-level filtering, an API to add custom attributes to logs, and updated instrumentation for Action Cable. It also provides fixes for how `Fiber` args are treated, Code-Level Metrics, and `NewRelic::Agent::Logging::DecoratingFormatter#clear_tags!` being incorrectly private.
Version <dev> of the agent adds log-level filtering, adds custom attributes for log events, and updates instrumentation for Action Cable. It also provides fixes for how `Fiber` args are treated, Code-Level Metrics, and `NewRelic::Agent::Logging::DecoratingFormatter#clear_tags!` being incorrectly private.

- **Feature: Filter forwarded logs based on level**

Expand All @@ -14,15 +14,22 @@ Version <dev> of the agent adds log-level filtering, an API to add custom attrib

This setting uses [Ruby's Logger::Severity constants integer values](https://github.com/ruby/ruby/blob/master/lib/logger/severity.rb#L6-L17) to determine precedence.

- **Feature: Custom attributes for logs API**
- **Feature: Custom attributes for logs**

You can now add custom attributes to your log events using `NewRelic::Agent.add_custom_log_attributes`.
You can now add custom attributes to log events forwarded to New Relic! You can pass these attributes using an API and/or a configuration option.

For example: `NewRelic::Agent.add_custom_log_attributes(dyno: ENV['DYNO'], pod_name: ENV['POD_NAME'])`, will add the attributes `dyno` and `pod_name` to your log events. Attributes passed to this API will be added to all log events.
| Configuration name | Default | Behavior |
| --------------------------- | ------- | ------------------------------------------------------ |
| `application_logging.forwarding.custom_attributes` | `{}` | A hash with key/value pairs to add as custom attributes to all log events forwarded to New Relic. If sending using an environment variable, the value must be formatted like: "key1=value1,key2=value2" |


Call the API using `NewRelic::Agent.add_custom_log_attributes` and passing your attributes as a hash. For example, you could call: `NewRelic::Agent.add_custom_log_attributes(dyno: ENV['DYNO'], pod_name: ENV['POD_NAME'])`, to add the attributes `dyno` and `pod_name` to your log events.

Attributes passed to the API or the configuration will be added to all log events.

Thanks to [@rajpawar02](https://github.com/rajpawar02) for raising this issue and [@askreet](https://github.com/askreet) for helping us with the solution. [Issue#1141](https://github.com/newrelic/newrelic-ruby-agent/issues/1141), [PR#2084](https://github.com/newrelic/newrelic-ruby-agent/pull/2084)
Thanks to [@rajpawar02](https://github.com/rajpawar02) for raising this issue and [@askreet](https://github.com/askreet) for helping us with the solution. [Issue#1141](https://github.com/newrelic/newrelic-ruby-agent/issues/1141), [PR#2084](https://github.com/newrelic/newrelic-ruby-agent/pull/2084), [PR#2087](https://github.com/newrelic/newrelic-ruby-agent/pull/2087)

- **Feature: Instrument transmit_subscription_* Action Cable actions**
- **Feature: Instrument transmit_subscription-related Action Cable actions**

This change subscribes the agent to the Active Support notifications for:
* `transmit_subscription_confirmation.action_cable`
Expand Down
24 changes: 24 additions & 0 deletions lib/new_relic/agent/configuration/default_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,22 @@ def self.convert_to_list(value)
end
end

def self.convert_to_hash(value)
return value if value.is_a?(Hash)

if value.is_a?(String)
return value.split(',').each_with_object({}) do |item, hash|
key, value = item.split('=')
hash[key] = value
end
end

raise ArgumentError.new(
"Config value '#{value}' of " \
"class #{value.class} couldn't be turned into a Hash."
)
end

SEMICOLON = ';'.freeze
def self.convert_to_list_on_semicolon(value)
case value
Expand Down Expand Up @@ -771,6 +787,14 @@ def self.enforce_fallback(allowed_values: nil, fallback: nil)
* "unknown"
DESCRIPTION
},
:'application_logging.forwarding.custom_attributes' => {
:default => {},
:public => true,
:type => Hash,
:transform => DefaultSource.method(:convert_to_hash),
:allowed_from_server => false,
:description => 'A hash with key/value pairs to add as custom attributes to all log events forwarded to New Relic. If sending using an environment variable, the value must be formatted like: "key1=value1,key2=value2"'
},
:'application_logging.forwarding.max_samples_stored' => {
:default => 10000,
:public => true,
Expand Down
3 changes: 3 additions & 0 deletions lib/new_relic/agent/log_event_aggregator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class LogEventAggregator < EventAggregator
FORWARDING_ENABLED_KEY = :'application_logging.forwarding.enabled'
DECORATING_ENABLED_KEY = :'application_logging.local_decorating.enabled'
LOG_LEVEL_KEY = :'application_logging.forwarding.log_level'
CUSTOM_ATTRIBUTES_KEY = :'application_logging.forwarding.custom_attributes'

attr_reader :attributes

Expand Down Expand Up @@ -181,6 +182,8 @@ def register_for_done_configuring(events)
record_configuration_metric(METRICS_SUPPORTABILITY_FORMAT, METRICS_ENABLED_KEY)
record_configuration_metric(FORWARDING_SUPPORTABILITY_FORMAT, FORWARDING_ENABLED_KEY)
record_configuration_metric(DECORATING_SUPPORTABILITY_FORMAT, DECORATING_ENABLED_KEY)

add_custom_attributes(NewRelic::Agent.config[CUSTOM_ATTRIBUTES_KEY])
end
end

Expand Down
19 changes: 19 additions & 0 deletions test/new_relic/agent/configuration/default_source_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,25 @@ def test_instrumentation_logger_matches_application_logging_disabled
end
end

def test_convert_to_hash_returns_hash
result = {'key1' => 'value1', 'key2' => 'value2'}

assert_equal(DefaultSource.convert_to_hash(result), result)
end

def test_convert_to_hash_with_string
value = 'key1=value1,key2=value2'
result = {'key1' => 'value1', 'key2' => 'value2'}

assert_equal(DefaultSource.convert_to_hash(value), result)
end

def test_convert_to_hash_raises_error_with_wrong_data_type
value = [1, 2, 3]

assert_raises(ArgumentError) { DefaultSource.convert_to_hash(value) }
end

def get_config_value_class(value)
type = value.class

Expand Down
13 changes: 13 additions & 0 deletions test/new_relic/agent/log_event_attributes_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,5 +211,18 @@ def test_drops_attribute_pair_if_invalid_value_class
logger.verify
end
end

def test_log_attributes_from_config
key = 'configured'
value = 'value'

with_config(
:'application_logging.forwarding.custom_attributes' => {key => value}
) do
NewRelic::Agent.config.notify_server_source_added

assert_includes(common_attributes_from_melt, key)
end
end
end
end

0 comments on commit 1fca78c

Please sign in to comment.