cloudreach-logger 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/cloudreach-logger.rb +114 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -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: []
|