Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fundingcircle/loga
Unified logging across environments
https://github.com/fundingcircle/loga
fluentd-plugin gelf-format logging rack rails railtie sinatra
Last synced: 7 days ago
JSON representation
Unified logging across environments
- Host: GitHub
- URL: https://github.com/fundingcircle/loga
- Owner: FundingCircle
- License: bsd-3-clause
- Created: 2015-05-13T16:55:58.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2024-02-29T12:11:29.000Z (9 months ago)
- Last Synced: 2024-10-07T04:28:58.254Z (about 1 month ago)
- Topics: fluentd-plugin, gelf-format, logging, rack, rails, railtie, sinatra
- Language: Ruby
- Homepage:
- Size: 494 KB
- Stars: 8
- Watchers: 92
- Forks: 2
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Loga
[![Gem Version](https://badge.fury.io/rb/loga.svg)](https://badge.fury.io/rb/loga)
![CI Build status](https://github.com/FundingCircle/loga/actions/workflows/build-and-test.yml/badge.svg?branch=master)
[![Code Quality](https://codeclimate.com/repos/5563694f6956805723005d2f/badges/8eecb9144730614fb39e/gpa.svg)](https://codeclimate.com/repos/5563694f6956805723005d2f/feed)
[![Test Coverage](https://codeclimate.com/repos/5563694f6956805723005d2f/badges/8eecb9144730614fb39e/coverage.svg)](https://codeclimate.com/repos/5563694f6956805723005d2f/coverage)
[![Dependency Status](https://img.shields.io/librariesio/release/rubygems/loga)](https://libraries.io/rubygems/loga)## Description
Loga provides consistent logging across frameworks and environments.
Includes:
- One tagged logger for all environments
- Human readable logs for development
- Structured logs for production ([GELF](http://docs.graylog.org/en/2.1/pages/gelf.html))
- One Rack logger for all Rack based applications## TOC
- [Installation](#installation)
- [Rails](#rails)
- [Reduced logs](#reduced-logs)
- [Request log tags](#request-log-tags)
- [Sinatra](#sinatra)
- [Output example](#output-example)
- [GELF Format](#gelf-format)
- [Simple Format](#simple-format)
- [Road map](#road-map)
- [Contributing](#contributing)
- [Running tests](#running-tests)
- [Credits](#credits)
- [License](#license)## Installation
Add this line to your application's Gemfile:
```
gem 'loga'
```### Rails
Let Loga know what your application name is and Loga will do the rest.
```ruby
# config/application.rb
class MyApp::Application < Rails::Application
config.loga = { service_name: 'my_app' }
end
```Loga hooks into the Rails logger initialization process and defines its own logger for all environments.
The logger configuration is adjusted based on the environment:
| | Production | Test | Development | Others |
|--------|------------|--------------|-------------|--------|
| Output | STDOUT | log/test.log | STDOUT | STDOUT |
| Format | gelf | simple | simple | simple |You can customize the configuration to your liking:
```ruby
# config/application.rb
class MyApp::Application < Rails::Application
config.loga = {
device: File.open("log/application.log", 'a'),
format: :gelf,
service_name: 'my_app',
}
end
```Loga leverages existing Rails configuration options:
- `config.filter_parameters`
- `config.log_level`
- `config.log_tags`Use these options to customize Loga instead of the Loga options hash.
Inside your application use `Rails.logger` instead of `Loga.logger`, even though
they are equivalent, to prevent lock-in.#### Reduced logs
When the format set to `gelf` requests logs are reduced to a single log entry, which
could include an exception.This is made possible by silencing these loggers:
- `Rack::Request::Logger`
- `ActionDispatch::DebugExceptions`
- `ActionController::LogSubscriber`
- `ActionView::LogSubscriber`
- `ActionMailer::LogSubscriber`#### Request log tags
To provide consistency between Rails and other Rack frameworks, tags (e.i `config.log_tags`)
are computed with a [Loga::Rack::Request](lib/loga/rack/request.rb) as
opposed to a `ActionDispatch::Request`.### Sinatra
With Sinatra Loga needs to be configured manually:
```ruby
# config.ru
require 'sinatra/base'
require 'loga'Loga.configure(
filter_parameters: [:password],
format: :gelf,
service_name: 'my_app',
tags: [:uuid],
)class MyApp < Sinatra::Base
set :logging, false # suppress Sinatra request loggerget '/' do
Loga.logger.info('Everything is Awesome!')
'Hello World!'
end
enduse Loga::Rack::RequestId
use Loga::Rack::Loggerrun MyApp
```You can now use `Loga.logger` or assign it to your existing logger.
The above configuration also inserts two middleware:- `Loga::Rack::RequestId` makes the request id available to the request logger
- `Loga::Rack::Logger` logs requestsYou can easily switch between formats by using the `LOGA_FORMAT`
environment variable. The `format` key in the options takes precedence over the
environment variable therefore it must be removed.```
LOGA_FORMAT=simple rackup
```### Sidekiq
Loga `2.7` provides an out-of-the-box support for `Sidekiq ~> 7.0`.
## Output Example
### GELF Format
Rails request logger: (includes controller/action name):
`curl localhost:3000/ok -X GET -H "X-Request-Id: 12345"`
```json
{
"_request.status": 200,
"_request.method": "GET",
"_request.path": "/ok",
"_request.params": {},
"_request.request_id": "12345",
"_request.request_ip": "127.0.0.1",
"_request.user_agent": null,
"_request.controller": "ApplicationController#ok",
"_request.duration": 0,
"_type": "request",
"_service.name": "my_app",
"_service.version": "1.0",
"_tags": "12345",
"short_message": "GET /ok 200 in 0ms",
"timestamp": 1450150205.123,
"host": "example.com",
"level": 6,
"version": "1.1"
}
```Sinatra request output is identical to Rails but without the `_request.controller` key.
Logger output:
```ruby
# Rails.logger
# or
# Loga.loggerLoga.configure(service_name: 'my_app', format: :gelf)
Loga.logger.info('I love Loga')
Loga.logger.tagged(%w(USER_123 CRM)) do
Loga.logger.info('I love Loga with tags')
end
``````json
{
"_service.name": "my_app",
"_service.version": "v1.0.0",
"_tags": "",
"host": "example.com",
"level": 6,
"short_message": "I love Loga",
"timestamp": 1479402679.663,
"version": "1.1"
}
``````json
{
"_service.name": "my_app",
"_service.version": "v1.0.0",
"_tags": "USER_123 CRM",
"host": "example.com",
"level": 6,
"short_message": "I love Loga",
"timestamp": 1479402706.102,
"version": "1.1"
}
```### Simple Format
Request logger:
`curl localhost:3000/ok -X GET -H "X-Request-Id: 12345"`
Rails
```
I, [2016-11-15T16:05:03.614081+00:00 #1][12345] Started GET "/ok" for ::1 at 2016-11-15 16:05:03 +0000
I, [2016-11-15T16:05:03.620176+00:00 #1][12345] Processing by ApplicationController#ok as HTML
I, [2016-11-15T16:05:03.624807+00:00 #1][12345] Rendering text template
I, [2016-11-15T16:05:03.624952+00:00 #1][12345] Rendered text template (0.0ms)
I, [2016-11-15T16:05:03.625137+00:00 #1][12345] Completed 200 OK in 5ms (Views: 4.7ms)
```Sinatra
```
I, [2016-11-15T16:10:08.645521+00:00 #1][12345] GET /ok 200 in 0ms type=request data={:request=>{"status"=>200, "method"=>"GET", "path"=>"/ok", "params"=>{}, "request_id"=>"12345", "request_ip"=>"127.0.0.1", "user_agent"=>nil, "duration"=>0}}
```Logger output:
```ruby
Loga.configure(service_name: 'my_app', format: :simple)Loga.logger.info('I love Loga')
Loga.logger.tagged(%w(USER_123 CRM)) do
Loga.logger.info('I love Loga with tags')
end
``````
I, [2016-11-17T17:07:46.714215+00:00 #595] I love Loga
I, [2016-11-17T17:07:46.725624+00:00 #595][USER_123 CRM] I love Loga with tags
```## Road map
Consult the [milestones](https://github.com/FundingCircle/loga/milestones).
## Contributing
Loga is in active development, feedback and contributions are welcomed.
### Running tests
This project uses [`appraisal`](https://github.com/thoughtbot/appraisal/tree/v2.0.2)
to run tests against different versions of dependencies (e.g. Rails, Sinatra).Install Loga dependencies with `bundle install` and then appraisals
with `bundle exec appraisal install`.Run all tests with `bundle exec appraisal rspec`.
You can run tests for one appraisal with `bundle exec appraisal appraisal-name rspec`.
Refer to the [Appraisals](Appraisals) file for a complete lists of appraisals.Prefix test command with RACK\_ENV to switch between environments for Rack based tests
`RACK_ENV=production bundle exec appraisal rspec`.Experiment Guard support introduced to ease running tests locally `bundle exec guard`.
[CI](https://circleci.com/gh/FundingCircle/loga) results are the source of truth.
## Credits
- [Lograge](https://github.com/roidrage/lograge)
- [LogStashLogger](https://github.com/dwbutler/logstash-logger)
- [Rails](https://github.com/rails/rails)
- [RackLogstasher](https://github.com/alphagov/rack-logstasher)## License
Copyright (c) 2015 Funding Circle. All rights reserved.
Distributed under the BSD 3-Clause License.