Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ jobs:
bash -c "
rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
[[ $? -ne 2 ]]
"
"
- name: Upload Sarif output
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: rubocop.sarif
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Telemetry::Logger

## v0.2.0
* Adding new module called `Telemetry::Logger::ExceptionHandler`
* Adding methods for `exception` and magic for detecting `ElasticAPM` and `OpenTelemetry`
* Adding `Upload Sarif output` step to `rubocop` GitHub action
* Adding `SECURITY.md` file

## v0.1.1
* Fixing issue with color option using the wrong method name
* Removing format logger from the setup command
Expand Down
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
# Telemetry::Logger
A generic gem to handle logging for all other telemetry gems

Example
#### Setting up the logger
```ruby
Telemetry::Logger.setup(level: 'warn', color: false, log_file: './telemetry.log')

opts = {
include_pid: false,
level: 'info',
log_file: nil,
color: true,
application: 'telemetry',
app_version: Telemetry::Logger::VERSION
}
```

#### Example Logging
```ruby
Telemetry::Logger.setup(level: 'info')
Telemetry::Logger.info 'test info'

Telemetry::Logger.debug 'test debug'
Telemetry::Logger.warn 'test warn'
Telemetry::Logger.error 'test error'
Telemetry::Logger.fatal 'test fatal'
Telemetry::Logger.unknown 'test unknown'
```

#### Example Exception Tracking
Instead of repeating the same error method all over the place for exceptions, you can use the `exception` method to
save on complexity and automatically report exceptions to supported APMs

```ruby
Telemetry::Logger.setup(level: 'info')
Telemetry::Logger.exception(StandardError.new('test error'), level: 'warn')
Telemetry::Logger.exception(StandardError.new('test error'), level: 'fatal')
Telemetry::Logger.exception(StandardError.new('test error'), handled: true)
Telemetry::Logger.exception(StandardError.new('test error'), backtrace: true)

# options for exception method
opts = {
level: 'error', # sets the log level
handled: true, # tells the apms if we handled this exception
backtrace: true, # should we log the backtrace?
backtrace_limit: 20, # how many lines should we limit the backtrace to?
raise: false, # should we reraise this exception instead of swallowing it?
}
```
19 changes: 19 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Security Policy

## Supported Versions

Use this section to tell people about which versions of your project are
currently being supported with security updates.

| Version | Supported |
| ------- | ------------------ |
| 0.x.x | :white_check_mark: |


## Reporting a Vulnerability

Use this section to tell people how to report a vulnerability.

Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc.
3 changes: 3 additions & 0 deletions lib/telemetry/logger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
require 'telemetry/logger/defaults'
require 'telemetry/logger/builder'
require 'telemetry/logger/methods'
require 'telemetry/logger/exception_handler'

module Telemetry
module Logger
class << self
include Telemetry::Logger::Defaults
include Telemetry::Logger::Methods
include Telemetry::Logger::Builder
include Telemetry::Logger::ExceptionHandler

def setup(level: 'info', **opts)
@opts = opts
output(**opts)
self.log_level = level
self
Expand Down
33 changes: 33 additions & 0 deletions lib/telemetry/logger/exception_handler.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module Telemetry
module Logger
module ExceptionHandler
def exception(exc, level: 'error', backtrace: true, backtrace_limit: 20, **opts)
level = 'unknown' unless %w[debug info warn error fatal].include? level.to_s
Telemetry::Logger.send(level, "#{exc.class}: #{exc.message}")
Telemetry::Logger.send(level, exc.backtrace[0..backtrace_limit]) if backtrace && !exc.backtrace.nil?

send_to_apm(exc, level: level)

raise(exc) if opts[:raise]
end

def send_to_apm(exc, **opts)
handled = opts[:handled] || %w[info debug].include?(opts[:level])
::ElasticAPM.report(exc, handled: handled) if elastic_apm?
::OpenTelemetry.handle_error(exception: exc, message: exc.message) if open_telemetry?
end

def elastic_apm?
@elastic_apm unless @elastic_apm.nil?

@elastic_apm = Kernel.const_defined? 'ElasticAPM'
end

def open_telemetry?
@open_telemetry unless @open_telemetry.nil?

@open_telemetry = Kernel.const_defined? 'OpenTelemetry'
end
end
end
end
2 changes: 1 addition & 1 deletion lib/telemetry/logger/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Telemetry
module Logger
VERSION = '0.1.1'.freeze
VERSION = '0.2.0'.freeze
end
end
31 changes: 31 additions & 0 deletions spec/exception_handler_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require 'spec_helper'
require 'telemetry/logger/exception_handler'

RSpec.describe Telemetry::Logger::ExceptionHandler do
it { should be_a Module }
before :all do
@class = Class.new do
# include Telemetry::Logger::ExceptionHandler
def initialize
extend Telemetry::Logger::ExceptionHandler
end
end

Telemetry::Logger.log_level = 'debug'

@exception = StandardError.new('this is my test exception')
end

it 'should be able to log exceptions' do
expect(@class.new.exception(@exception))
expect { @class.new.exception(@exception, level: 'debug') }.to output(/DEBUG/).to_stdout_from_any_process
expect { @class.new.exception(@exception, level: 'info') }.to output(/INFO/).to_stdout_from_any_process
expect { @class.new.exception(@exception, level: 'warn') }.to output(/WARN/).to_stdout_from_any_process
expect { @class.new.exception(@exception, level: 'error') }.to output(/ERROR/).to_stdout_from_any_process
expect { @class.new.exception(@exception, level: 'fatal') }.to output(/FATAL/).to_stdout_from_any_process
end

it 'should be able to re raise an exception' do
expect { @class.new.exception(StandardError.new('test'), raise: true) }.to raise_exception StandardError
end
end