GithubHelp home page GithubHelp logo

bmarkons / logman Goto Github PK

View Code? Open in Web Editor NEW

This project forked from renderedtext/logman

0.0 0.0 0.0 50 KB

Logman — Lightweight abstraction for formatted logging

License: MIT License

Ruby 99.18% Shell 0.82%

logman's Introduction

Logman

Build Status

Logman introduces a unified logging format in your project. Every log line is an event that is logged to the STDOUT or to file.

Installation

Add this line to your application's Gemfile:

gem "rt-logman"

Basic Usage

To log an informative message to STDOUT, use the following code snippet:

Logman.info("Hello World")

# Output:
# {"level":"INFO","time":"2017-12-12 09:33:00 +0000","pid":10950,"message":"Hello World"}

Every log event can be extended with metadata — a hash with key value pairs:

Logman.info("Hello World", :from => "renderedtext", :to => "The World")

# Output:
# {"level":"INFO","time":"2017-12-12 09:33:21 +0000","pid":10950,"message":"Hello World","from":"renderedtext","to":"The World"}

Every log event has a severity. In the previous examples we have used info. To log an error use the following snippet:

Logman.error("Team does not exists", :owner => "renderedtext", :team_name => "z-fightes")

# Output:
# {"level":"ERROR","time":"2017-12-12 09:33:47 +0000","pid":10950,"message":"Team does not exists","owner":"renderedtext","team_name":"z-fightes"}

Logman supports multiple severity levels:

Logman.fatal("Hello")
Logman.error("Hello")
Logman.warn("Hello")
Logman.info("Hello")
Logman.debug("Hello")

Where the following hierarchy stands:

FATAL > ERROR > WARN > INFO > DEBUG

Instantiated Loggers

Logs in a class or system component usually share common metadata fields. For this purpose, a new instance of Logman can be created and pre-populated with metadata.

In the following example, we will add logs to a video processor:

class VideoProcessor

  def initialize(video)
    @logger = Logman.new

    # these fields will appear in every log event
    @logger.add(:component => "video_processor")
    @logger.add(:id => @video.id)
    @logger.add(:title => "Keyboard Cat")
  end

  def process
    @logger.info("started")

    content = load_from_disk(@video.location)
    @logger.info("loaded into memory", :size => content.length)

    compressed_content = compress(@video)
    @logger.info("compressed", :size => compressed_content.length)

    s3_path = upload_to_s3(@video)
    @logger.info("uploaded to S3", :s3_path => s3_path

    @video.update(:s3_path => s3_path)

    @logger.info("finished")
  rescue => exception
    @logger.error("failed", :exception => exception.message)

    raise
  end

end

In case of a successful processing of a video, we would see the following:

{"level":"INFO","time":"2017-12-12 09:35:19 +0000","pid":10950,"message":"started","component":"video_processor","id":9312,"title":"Keyboard Cat"}
{"level":"INFO","time":"2017-12-12 09:35:34 +0000","pid":10950,"message":"loaded into memory","component":"video_processor","id":9312,"title":"Keyboard Cat","size":41241241}
{"level":"INFO","time":"2017-12-12 09:35:44 +0000","pid":10950,"message":"compressed","component":"video_processor","id":9312,"title":"Keyboard Cat","size":1312312}
{"level":"INFO","time":"2017-12-12 09:36:08 +0000","pid":10950,"message":"uploaded to S3","component":"video_processor","id":9312,"title":"Keyboard Cat","s3_path":"s3://hehe/a.mpeg"}
{"level":"INFO","time":"2017-12-12 09:36:27 +0000","pid":10950,"message":"finished","component":"video_processor","id":9312,"title":"Keyboard Cat"}

In case of an error, we would see the following:

{"level":"INFO","time":"2017-12-12 09:35:19 +0000","pid":10950,"message":"started","component":"video_processor","id":9312,"title":"Keyboard Cat"}
{"level":"ERROR","time":"2017-12-12 09:35:34 +0000","pid":10950,"message":"failed","component":"video_processor","id":9312,"title":"Keyboard Cat","size":41241241,"exception": "Out of memory"}

Logman can receive a Ruby Logger instance to handle output. This is useful if you want to log to a file.

@logger = Logman.new(:logger => Logger.new("/tmp/out.txt"))

@logger.info("Hello World")

# => output goes to /tmp/out.txt

You can also pass an instance of Rails logger:

@logger = Logman.new(:logger => Rails.logger)

@logger.info("Hello World")

Or, you can pass an instance of another Logman. This is useful if you want to create a new Logman instance with the same fields as the previous instance:

@api_logger = Logman.new
@api_logger.add(:version => "v2")

@team_api_logger = Logman.new(:logger => @api_logger)
# team logger copied the `version` field

@team_api_logger.info("Hello")

# {"level":"INFO","time":"2017-12-12 09:39:07 +0000","pid":10950,"message":"Hello","version":"v2"}

With Logman, you can instrument data processing with a logger block. For example, if you want to log the steps in a user sign-up progress:

Logman.process("user-registration", :username => "shiroyasha") do |logger|
  user = User.create(params)
  logger.info("User Record Created")

  SigupEmail.send(user)
  logger.info("Sent signup email")

  team.add(user)
  logger.info("Added user to a team", :team_id => team.id)
end

The above will log the following information:

{"level":"INFO","time":"2017-12-12 09:40:39 +0000","pid":10950,"message":"user-registration-started","username":"shiroyasha"}
{"level":"INFO","time":"2017-12-12 09:40:39 +0000","pid":10950,"message":"User Record Created","username":"shiroyasha"}
{"level":"INFO","time":"2017-12-12 09:40:39 +0000","pid":10950,"message":"Sent signup email","username":"shiroyasha"}
{"level":"INFO","time":"2017-12-12 09:40:39 +0000","pid":10950,"message":"Added user to a team","username":"shiroyasha","team_id":21}
{"level":"INFO","time":"2017-12-12 09:40:39 +0000","pid":10950,"message":"user-registration-finished","username":"shiroyasha"}

In case of an exception, the error will be logged and re-thrown:

Logman.process("user-registration", :username => "shiroyasha") do |logger|
  user = User.create(params)
  logger.info("User Record Created")

  SigupEmail.send(user)
  logger.info("Sent signup email")

  raise "Exception"

  team.add(user)
  logger.info("Added user to a team", :team_id => team)
end
{"level":"INFO","time":"2017-12-12 09:41:27 +0000","pid":10950,"message":"user-registration-started","username":"shiroyasha"}
{"level":"INFO","time":"2017-12-12 09:41:27 +0000","pid":10950,"message":"User Record Created","username":"shiroyasha"}
{"level":"INFO","time":"2017-12-12 09:41:27 +0000","pid":10950,"message":"Sent signup email","username":"shiroyasha"}
{"level":"ERROR","time":"2017-12-12 09:41:27 +0000","pid":10950,"message":"Exception","username":"shiroyasha","type":"RuntimeError"}

Development

After checking out the repo:

  • run bundle install to install dependencies
  • run bundle exec rspec to run unit specs
  • run bundle exec rubocop to check code style
  • run bundle exec reek to check code smells

To release a new version:

  • bump the version in lib/logman/version.rb
  • run bundle exec rake release to release a new version on RubyGems

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/renderedtext/logman. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Logman project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

logman's People

Contributors

shiroyasha avatar nikolalsvk avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.