cloudreach-logger 1.0.4

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cloudreach-logger.rb +114 -0
  3. metadata +58 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 04a9b586d3de32b7d29e0a9d430a85cd675eaaf6
4
+ data.tar.gz: 8e4d6402741e1c0ca71325cd91a5ab14c7e4e3d4
5
+ SHA512:
6
+ metadata.gz: 9f4fa7ee23f43804c98c028677eaeef9e5a895e4f9f7970c5d0b6279e2bee65b9f890d94fe2dc700eb1f74aef118bbb134d20ba305caf19efefdbeec57bfb882
7
+ data.tar.gz: 4bd241b982f5a28bbd5f295587f48fab4337becb94f5a5be0c44474a6e500c31d6140927f8bb5fb39251ebbd9b84411b36780ef8a5270edba6198a27532b1e0e
@@ -0,0 +1,114 @@
1
+ # Splunk friendly logger
2
+
3
+ # Accepts either a string or a hash.
4
+ # A hash will be serialized into splunk friendly key value pairs like key1=value, key2="some value" ...
5
+ # A string will be logged out with the key line="my log message"
6
+
7
+ require 'logger'
8
+
9
+ # HACK: this patches the logger class so we can set pairs of values
10
+ # to append to every log after initialisation (e.g request_id)
11
+ #
12
+ # TODO: write a proper logger class for ourselves
13
+ class Logger
14
+ attr_accessor :_pairs
15
+
16
+ def set(**params)
17
+ @_pairs = @_pairs || {}
18
+ @_pairs = @_pairs.merge(params)
19
+ end
20
+ end
21
+
22
+ module Cloudreach
23
+ class MultiIO
24
+ def initialize(*targets)
25
+ @targets = targets
26
+ end
27
+
28
+ def write(*args)
29
+ @targets.each do |target|
30
+ target.write(*args)
31
+ end
32
+ end
33
+
34
+ def close
35
+ @targets.each(&:close)
36
+ end
37
+ end
38
+
39
+ # this class is just a factory that produces instances of Ruby's own Logger class
40
+ class Logger
41
+ @@log_levels = {
42
+ :debug => ::Logger::DEBUG,
43
+ :info => ::Logger::INFO,
44
+ :warn => ::Logger::WARN,
45
+ :error => ::Logger::ERROR,
46
+ :fatal => ::Logger::FATAL
47
+ }
48
+
49
+ def self.create(logfile: nil, level: :debug, stdout: false, name: nil)
50
+ if name == nil
51
+ # default to using folder name as name
52
+ name = ENV['PWD']
53
+ name = name.slice(name.rindex('/')+1, name.length)
54
+ end
55
+
56
+ if logfile == nil
57
+ env = ENV['RUBY_ENV'] || ENV['RACK_ENV'] || 'development'
58
+ logfile = "log/#{env}.log"
59
+ end
60
+
61
+ if !logfile && !stdout
62
+ raise ArgumentError, "You aren't going to log anything. What?"
63
+ end
64
+
65
+ if logfile
66
+ file = File.open(logfile, 'a')
67
+ file.sync = true
68
+ end
69
+
70
+ if logfile && stdout
71
+ file = MultiIO.new(file, STDOUT)
72
+ elsif !logfile && stdout
73
+ file = STDOUT
74
+ end
75
+
76
+ logger = ::Logger.new(file)
77
+ logger.level = @@log_levels[level]
78
+ logger.formatter = lambda { |severity, timestamp, progname, msg|
79
+ if msg.is_a? Hash
80
+ pairs = splunkify(msg)
81
+ else
82
+ pairs = "line=#{sanitize(msg)}"
83
+ end
84
+
85
+ if logger._pairs
86
+ pairs = "#{splunkify(logger._pairs)}, #{pairs}"
87
+ end
88
+
89
+ "[#{timestamp.strftime("%Y-%m-%d %H:%M:%S")}] service_name=#{sanitize(name)}, severity=#{severity}, #{pairs}\n"
90
+ }
91
+
92
+ logger.set(instance_id: ENV['CLOUDREACH_INSTANCE_ID']) if ENV['CLOUDREACH_INSTANCE_ID']
93
+ logger.set(container_id: ENV['CLOUDREACH_CONTAINER_ID']) if ENV['CLOUDREACH_CONTAINER_ID']
94
+
95
+ logger
96
+ end
97
+
98
+ private
99
+
100
+ # strip out newlines, add quotes if there's whitespace, & escape double quotes
101
+ def self.sanitize(value)
102
+ value = value.to_s.gsub(/(\n|\r)/, ' ')
103
+ value = value.gsub(/(?<!\\)(?:\\{2})*\K"/) { %q(\") } # match unescaped quotes
104
+ value = "\"#{value}\"" if value.match /\s/
105
+ value
106
+ end
107
+
108
+ # munge a hash into key/value pairs
109
+ def self.splunkify(hash)
110
+ pairs = hash.map { |key, value| "#{key}=#{sanitize(value)}" }
111
+ pairs.join ', '
112
+ end
113
+ end
114
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cloudreach-logger
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.4
5
+ platform: ruby
6
+ authors:
7
+ - John Houston
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logger
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.2.8
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.2.8
27
+ description: A gem to create splunk friendly logs
28
+ email: john.houston@cloudreach.co.uk
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/cloudreach-logger.rb
34
+ homepage: https://bitbucket.org/cloudreach/cloudreach-logger
35
+ licenses:
36
+ - Apache2
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 2.4.8
55
+ signing_key:
56
+ specification_version: 4
57
+ summary: Cloudreach Logger
58
+ test_files: []