sherlog-holmes 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.idea/.rakeTasks +7 -0
- data/.idea/copyright/MIT.xml +6 -0
- data/.idea/copyright/profiles_settings.xml +5 -1
- data/.idea/misc.xml +0 -155
- data/.idea/sherlog-holmes.iml +17 -2
- data/.rspec +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +81 -2
- data/bin/sherlog +73 -40
- data/conf/patterns/jboss.yml +4 -0
- data/lib/sherlog_holmes.rb +62 -3
- data/lib/sherlog_holmes/entry.rb +59 -0
- data/lib/sherlog_holmes/filter.rb +107 -0
- data/lib/sherlog_holmes/parser.rb +109 -0
- data/lib/sherlog_holmes/result.rb +49 -0
- data/lib/sherlog_holmes/version.rb +23 -1
- data/sherlog-holmes.gemspec +1 -1
- metadata +15 -10
- data/lib/sherlog_holmes/log_entry.rb +0 -37
- data/lib/sherlog_holmes/log_file.rb +0 -88
- data/lib/sherlog_holmes/log_filter.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f7d4009b72347473254b169427804b5dfb0ed36
|
4
|
+
data.tar.gz: 9cad2d96b5b02ac7fedef91ba8b39c32a9c8d3eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 940283aab12cf1fd5ab55d81addca4812e3715bb411367294d2e7d64de9c4d94368ba0cf9a8b83db56962704cbfccf1ec7e37f887b5cc1e22b74ac0cefd72634
|
7
|
+
data.tar.gz: d105d4e8a515179053a92ae15149c54a3b3b80c001a3b5f201135402c176e3a98f2cd6a460572cfafcd91c9222819c672763cf580fa4596ff3971149c4ee860e
|
data/.idea/.rakeTasks
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<Settings><!--This file was automatically generated by Ruby plugin.
|
3
|
+
You are allowed to:
|
4
|
+
1. Remove rake task
|
5
|
+
2. Add existing rake tasks
|
6
|
+
To add existing rake tasks automatically delete this file and reload the project.
|
7
|
+
--><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build sherlog-holmes-0.2.0.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Build and install sherlog-holmes-0.2.0.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install sherlog-holmes-0.2.0.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v0.2.0 and build and push sherlog-holmes-0.2.0.gem to Rubygems" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<component name="CopyrightManager">
|
2
|
+
<copyright>
|
3
|
+
<option name="myName" value="MIT" />
|
4
|
+
<option name="notice" value="The MIT License (MIT) Copyright (c) &#36;today.year Marcelo "Ataxexe" Guimaraes <ataxexe@devnull.tools> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. " />
|
5
|
+
</copyright>
|
6
|
+
</component>
|
data/.idea/misc.xml
CHANGED
@@ -7,161 +7,6 @@
|
|
7
7
|
</MavenGeneralSettings>
|
8
8
|
</option>
|
9
9
|
</component>
|
10
|
-
<component name="ProjectInspectionProfilesVisibleTreeState">
|
11
|
-
<entry key="Project Default">
|
12
|
-
<profile-state>
|
13
|
-
<expanded-state>
|
14
|
-
<State>
|
15
|
-
<id />
|
16
|
-
</State>
|
17
|
-
<State>
|
18
|
-
<id>AOP</id>
|
19
|
-
</State>
|
20
|
-
<State>
|
21
|
-
<id>Abstraction issuesJava</id>
|
22
|
-
</State>
|
23
|
-
<State>
|
24
|
-
<id>Android Lint</id>
|
25
|
-
</State>
|
26
|
-
<State>
|
27
|
-
<id>Annotations verifyingGroovy</id>
|
28
|
-
</State>
|
29
|
-
<State>
|
30
|
-
<id>Assignment issuesJava</id>
|
31
|
-
</State>
|
32
|
-
<State>
|
33
|
-
<id>CDI(Contexts and Dependency Injection) issues</id>
|
34
|
-
</State>
|
35
|
-
<State>
|
36
|
-
<id>Class structureJava</id>
|
37
|
-
</State>
|
38
|
-
<State>
|
39
|
-
<id>Cloning issuesJava</id>
|
40
|
-
</State>
|
41
|
-
<State>
|
42
|
-
<id>Code style issuesJava</id>
|
43
|
-
</State>
|
44
|
-
<State>
|
45
|
-
<id>Code style issuesJavaScript</id>
|
46
|
-
</State>
|
47
|
-
<State>
|
48
|
-
<id>Encapsulation issuesJava</id>
|
49
|
-
</State>
|
50
|
-
<State>
|
51
|
-
<id>Error handlingJava</id>
|
52
|
-
</State>
|
53
|
-
<State>
|
54
|
-
<id>Finalization issuesJava</id>
|
55
|
-
</State>
|
56
|
-
<State>
|
57
|
-
<id>General</id>
|
58
|
-
</State>
|
59
|
-
<State>
|
60
|
-
<id>GeneralJavaScript</id>
|
61
|
-
</State>
|
62
|
-
<State>
|
63
|
-
<id>GeneralScala</id>
|
64
|
-
</State>
|
65
|
-
<State>
|
66
|
-
<id>Groovy</id>
|
67
|
-
</State>
|
68
|
-
<State>
|
69
|
-
<id>ImportsJava</id>
|
70
|
-
</State>
|
71
|
-
<State>
|
72
|
-
<id>Inheritance issuesJava</id>
|
73
|
-
</State>
|
74
|
-
<State>
|
75
|
-
<id>Internationalization issues</id>
|
76
|
-
</State>
|
77
|
-
<State>
|
78
|
-
<id>Internationalization issuesJava</id>
|
79
|
-
</State>
|
80
|
-
<State>
|
81
|
-
<id>J2ME issuesJava</id>
|
82
|
-
</State>
|
83
|
-
<State>
|
84
|
-
<id>JPA issues</id>
|
85
|
-
</State>
|
86
|
-
<State>
|
87
|
-
<id>JSON</id>
|
88
|
-
</State>
|
89
|
-
<State>
|
90
|
-
<id>Java</id>
|
91
|
-
</State>
|
92
|
-
<State>
|
93
|
-
<id>Java language level issuesJava</id>
|
94
|
-
</State>
|
95
|
-
<State>
|
96
|
-
<id>Java language level migration aidsJava</id>
|
97
|
-
</State>
|
98
|
-
<State>
|
99
|
-
<id>JavaScript</id>
|
100
|
-
</State>
|
101
|
-
<State>
|
102
|
-
<id>Javadoc issuesJava</id>
|
103
|
-
</State>
|
104
|
-
<State>
|
105
|
-
<id>Language Injection</id>
|
106
|
-
</State>
|
107
|
-
<State>
|
108
|
-
<id>Memory issuesJava</id>
|
109
|
-
</State>
|
110
|
-
<State>
|
111
|
-
<id>Modularization issuesJava</id>
|
112
|
-
</State>
|
113
|
-
<State>
|
114
|
-
<id>Numeric issuesJava</id>
|
115
|
-
</State>
|
116
|
-
<State>
|
117
|
-
<id>Performance issuesJava</id>
|
118
|
-
</State>
|
119
|
-
<State>
|
120
|
-
<id>Portability issuesJava</id>
|
121
|
-
</State>
|
122
|
-
<State>
|
123
|
-
<id>Potentially confusing code constructsGroovy</id>
|
124
|
-
</State>
|
125
|
-
<State>
|
126
|
-
<id>Potentially confusing code constructsJavaScript</id>
|
127
|
-
</State>
|
128
|
-
<State>
|
129
|
-
<id>Probable bugsGroovy</id>
|
130
|
-
</State>
|
131
|
-
<State>
|
132
|
-
<id>Probable bugsJava</id>
|
133
|
-
</State>
|
134
|
-
<State>
|
135
|
-
<id>Properties Files</id>
|
136
|
-
</State>
|
137
|
-
<State>
|
138
|
-
<id>Scala</id>
|
139
|
-
</State>
|
140
|
-
<State>
|
141
|
-
<id>ScaladocScala</id>
|
142
|
-
</State>
|
143
|
-
<State>
|
144
|
-
<id>Security issuesJava</id>
|
145
|
-
</State>
|
146
|
-
<State>
|
147
|
-
<id>Serialization issuesJava</id>
|
148
|
-
</State>
|
149
|
-
<State>
|
150
|
-
<id>Spring</id>
|
151
|
-
</State>
|
152
|
-
<State>
|
153
|
-
<id>Spring CoreSpring</id>
|
154
|
-
</State>
|
155
|
-
<State>
|
156
|
-
<id>Threading issuesGroovy</id>
|
157
|
-
</State>
|
158
|
-
<State>
|
159
|
-
<id>Threading issuesJava</id>
|
160
|
-
</State>
|
161
|
-
</expanded-state>
|
162
|
-
</profile-state>
|
163
|
-
</entry>
|
164
|
-
</component>
|
165
10
|
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
166
11
|
<OptionsSetting value="true" id="Add" />
|
167
12
|
<OptionsSetting value="true" id="Remove" />
|
data/.idea/sherlog-holmes.iml
CHANGED
@@ -1,18 +1,33 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<module type="RUBY_MODULE" version="4">
|
3
|
+
<component name="FacetManager">
|
4
|
+
<facet type="gem" name="Gem">
|
5
|
+
<configuration>
|
6
|
+
<option name="GEM_APP_ROOT_PATH" value="" />
|
7
|
+
<option name="GEM_APP_TEST_PATH" value="" />
|
8
|
+
<option name="GEM_APP_LIB_PATH" value="" />
|
9
|
+
</configuration>
|
10
|
+
</facet>
|
11
|
+
</component>
|
3
12
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
4
13
|
<exclude-output />
|
5
14
|
<content url="file://$MODULE_DIR$">
|
6
15
|
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
7
16
|
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
|
8
17
|
<sourceFolder url="file://$MODULE_DIR$/bin" isTestSource="false" />
|
18
|
+
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
9
19
|
</content>
|
10
20
|
<orderEntry type="inheritedJdk" />
|
11
21
|
<orderEntry type="sourceFolder" forTests="false" />
|
12
22
|
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.10.6, RVM: ruby-2.2-head) [gem]" level="application" />
|
13
|
-
<orderEntry type="library" scope="PROVIDED" name="
|
23
|
+
<orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, RVM: ruby-2.2-head) [gem]" level="application" />
|
24
|
+
<orderEntry type="library" scope="PROVIDED" name="rake (v10.4.2, RVM: ruby-2.2-head) [gem]" level="application" />
|
25
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec (v3.4.0, RVM: ruby-2.2-head) [gem]" level="application" />
|
26
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.4.1, RVM: ruby-2.2-head) [gem]" level="application" />
|
27
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.4.0, RVM: ruby-2.2-head) [gem]" level="application" />
|
28
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.4.0, RVM: ruby-2.2-head) [gem]" level="application" />
|
29
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.4.1, RVM: ruby-2.2-head) [gem]" level="application" />
|
14
30
|
<orderEntry type="library" scope="PROVIDED" name="term-ansicolor (v1.3.2, RVM: ruby-2.2-head) [gem]" level="application" />
|
15
|
-
<orderEntry type="library" scope="PROVIDED" name="test-unit (v3.1.5, RVM: ruby-2.2-head) [gem]" level="application" />
|
16
31
|
<orderEntry type="library" scope="PROVIDED" name="tins (v1.6.0, RVM: ruby-2.2-head) [gem]" level="application" />
|
17
32
|
<orderEntry type="library" scope="PROVIDED" name="yummi (v0.9.5, RVM: ruby-2.2-head) [gem]" level="application" />
|
18
33
|
</component>
|
data/.rspec
ADDED
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2015 Ataxexe
|
3
|
+
Copyright (c) 2015 Marcelo "Ataxexe" Guimaraes <ataxexe@devnull.tools>
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Sherlog Holmes
|
2
2
|
|
3
|
-
|
3
|
+
*Less data containing useful information is way better than lots of data containing a mess.*
|
4
|
+
|
5
|
+
Don't you hate thousands of lines in a log blowing up with your troubleshooting? Lots of useless data that you have to filter just to turn that 300 MB of madness into a 30 KB of useful information. If you need something that can rip off useless entries so you can have a clue about what is going on with that application, you should give Sherlog Holmes a try.
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -18,9 +20,86 @@ Or install it yourself as:
|
|
18
20
|
|
19
21
|
$ gem install sherlog-holmes
|
20
22
|
|
23
|
+
## Concepts
|
24
|
+
|
25
|
+
Sherlog works by grabbing every line of a log and parsing it into a simple structure containing:
|
26
|
+
|
27
|
+
- Time
|
28
|
+
- Level
|
29
|
+
- Category
|
30
|
+
- Origin
|
31
|
+
- Message
|
32
|
+
- Exception (if present)
|
33
|
+
- Stacktrace (if present)
|
34
|
+
|
35
|
+
You need to supply a regular expression that maps that fields to match your log entry. Here is an example:
|
36
|
+
|
37
|
+
```regexp
|
38
|
+
(<?level>\w+)\s(<?category>\s+)\s(<?message>.+)
|
39
|
+
```
|
40
|
+
|
41
|
+
Notice that you don't need to define every field, just the ones you need to filter.
|
42
|
+
|
43
|
+
Patterns for exception and stacktrace should be defined separately. The exception pattern is used only in the message field. Here is a complete example of a pattern configuration:
|
44
|
+
|
45
|
+
```yaml
|
46
|
+
jboss:
|
47
|
+
entry: (?<time>[0-9,.:]+)\s+(?<level>\w+)\s+\[(?<category>\S+)\]\s\((?<origin>[^)]+)\)?\s?(?<message>.+)
|
48
|
+
exception: (?<exception>\w+(\.\w+)+(Exception|Error))
|
49
|
+
stacktrace: ^(\s+at)|(Caused by\:)|(\s+\.{3}\s\d+\smore)
|
50
|
+
```
|
51
|
+
|
52
|
+
The configuration should contain a unique id and at least a pattern for the log **entry**. Place you configuration file in a `*.yml` file inside you `$HOME/.sherlog/patterns` directory and you're ready to go!
|
53
|
+
|
21
54
|
## Usage
|
22
55
|
|
23
|
-
Shelog Holmes provides
|
56
|
+
Shelog Holmes provides the command line tool `sherlog`. You can use this to pass a log, the filters you need to apply and the process that needs to be executed (like showing the filtered entries or counting the exceptions):
|
57
|
+
|
58
|
+
`-p, --patterns FILE`
|
59
|
+
|
60
|
+
Additionally to having definitions in your `$HOME/.sherlog` directory, you can pass a definition file from anywhere in your machine and Sherlog will scan and register the definitions.
|
61
|
+
|
62
|
+
`-c, --category EXPRESSION`
|
63
|
+
|
64
|
+
This will filter entries using the category field. You can use the wildcard `*` here.
|
65
|
+
|
66
|
+
`-l, --level EXPRESSION`
|
67
|
+
|
68
|
+
This will filter entries using the level field. You can use the wildcard `*` here.
|
69
|
+
|
70
|
+
`-o, --origin EXPRESSION`
|
71
|
+
|
72
|
+
This will filter entries using the origin field. You can use the wildcard `*` here.
|
73
|
+
|
74
|
+
`-m, --message EXPRESSION`
|
75
|
+
|
76
|
+
This will filter entries using the message field. You can use the wildcard `*` here.
|
77
|
+
|
78
|
+
`-e, --exception EXPRESSION`
|
79
|
+
|
80
|
+
This will filter entries using the exception field. You can use the wildcard `*` here.
|
81
|
+
|
82
|
+
*NOTICE: the expressions are case sensitive, wildcards can be used at start, end or both*
|
83
|
+
|
84
|
+
`--any-exception`
|
85
|
+
|
86
|
+
This will filter entries with exceptions, regardless the kind.
|
87
|
+
|
88
|
+
`--and`
|
89
|
+
|
90
|
+
This will use the **AND** operation to connect the next filter. This is the default operation.
|
91
|
+
|
92
|
+
`--or`
|
93
|
+
|
94
|
+
This will use the **OR** operation to connect the next filter.
|
95
|
+
|
96
|
+
sherlog --level WARN --or --level ERROR --and --any-exception
|
97
|
+
|
98
|
+
This is equivalent to:
|
99
|
+
|
100
|
+
(WARN || ERROR) && EXCEPTION
|
101
|
+
|
102
|
+
*NOTICE: you cannot do some fuzzy logics with these operations because there are no options to define the precedence*
|
24
103
|
|
25
104
|
## License
|
26
105
|
|
data/bin/sherlog
CHANGED
@@ -1,4 +1,25 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# The MIT License
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015 Marcelo "Ataxexe" Guimarães <ataxexe@devnull.tools>
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
14
|
+
# all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
# THE SOFTWARE.
|
2
23
|
|
3
24
|
require 'yummi'
|
4
25
|
require 'optionparser'
|
@@ -8,59 +29,65 @@ require_relative '../lib/sherlog_holmes'
|
|
8
29
|
include Sherlog
|
9
30
|
|
10
31
|
@opts = OptionParser::new
|
11
|
-
@
|
12
|
-
@
|
32
|
+
@stacktrace = true
|
33
|
+
@filter = nil
|
34
|
+
@operation = :and
|
35
|
+
@listeners = []
|
36
|
+
|
37
|
+
def add_filter(filter)
|
38
|
+
if @filter
|
39
|
+
@filter = @filter.send @operation, filter
|
40
|
+
else
|
41
|
+
@filter = filter
|
42
|
+
end
|
43
|
+
end
|
13
44
|
|
14
45
|
@opts.banner = 'Usage: sherlog [options] <logfile>'
|
15
46
|
|
16
|
-
@opts.on '-
|
17
|
-
|
47
|
+
@opts.on '-p FILE', '--patterns FILE', 'Configures the patterns' do |file|
|
48
|
+
Sherlog.load_patterns file
|
18
49
|
end
|
19
50
|
|
20
|
-
@opts.on '-
|
21
|
-
|
51
|
+
@opts.on '-c EXPRESSION', '--category EXPRESSION', 'Set the category filter expression' do |expression|
|
52
|
+
add_filter Filter::category(expression)
|
22
53
|
end
|
23
54
|
|
24
|
-
|
25
|
-
|
26
|
-
if @filter_params[:level]
|
27
|
-
@filter_params[:level] += "|#{level}"
|
28
|
-
else
|
29
|
-
@filter_params[:level] = level.to_s
|
30
|
-
end
|
31
|
-
end
|
55
|
+
@opts.on '-l EXPRESSION', '--level EXPRESSION', 'Set the level filter expression' do |expression|
|
56
|
+
add_filter Filter::level(expression)
|
32
57
|
end
|
33
58
|
|
34
|
-
@opts.on '-
|
35
|
-
|
59
|
+
@opts.on '-o EXPRESSION', '--origin EXPRESSION', 'Sets the origin filter expression' do |expression|
|
60
|
+
add_filter Filter::origin(expression)
|
36
61
|
end
|
37
62
|
|
38
|
-
@opts.on '-
|
39
|
-
|
63
|
+
@opts.on '-m EXPRESSION', '--message EXPRESSION', 'Set the message filter expression' do |expression|
|
64
|
+
add_filter Filter::message(expression)
|
40
65
|
end
|
41
66
|
|
42
|
-
@opts.on '
|
43
|
-
|
67
|
+
@opts.on '-e EXPRESSION', '--exception EXPRESSION', 'Sets the exception filter expression' do |expression|
|
68
|
+
add_filter Filter::exception(expression)
|
44
69
|
end
|
45
70
|
|
46
|
-
@opts.on '--
|
47
|
-
|
71
|
+
@opts.on '--any-exception', 'Filter exception entries' do
|
72
|
+
add_filter Filter::exceptions
|
48
73
|
end
|
49
74
|
|
50
|
-
@opts.on '--
|
51
|
-
@
|
75
|
+
@opts.on '--and', 'Sets the next filter to use the AND operator' do
|
76
|
+
@operation = :and
|
52
77
|
end
|
53
78
|
|
54
|
-
@opts.on '--
|
55
|
-
@
|
79
|
+
@opts.on '--or', 'Sets the next filter to use the OR operation' do
|
80
|
+
@operation = :or
|
56
81
|
end
|
57
82
|
|
58
|
-
@opts.on '
|
59
|
-
@
|
83
|
+
@opts.on '-t TYPE', '--type TYPE', 'Sets the type of the log (for loading patterns)' do |type|
|
84
|
+
@type = type.to_sym
|
60
85
|
end
|
61
86
|
|
62
|
-
@opts.on '--
|
63
|
-
@
|
87
|
+
@opts.on '--print', 'Prints the filtered entries' do
|
88
|
+
@listeners << lambda do |entry|
|
89
|
+
puts entry.raw_content
|
90
|
+
end
|
64
91
|
end
|
65
92
|
|
66
93
|
@opts.on '-h', '--help', 'Shows the usage help' do
|
@@ -71,14 +98,20 @@ end
|
|
71
98
|
@opts.parse! ARGV
|
72
99
|
|
73
100
|
file = ARGV.first
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
101
|
+
parser = Sherlog.parser @type if @type
|
102
|
+
parser ||= Parser::new
|
103
|
+
parser.filter @filter
|
104
|
+
@listeners.each do |listener|
|
105
|
+
parser.on_new_entry listener
|
106
|
+
end
|
107
|
+
begin
|
108
|
+
if file
|
109
|
+
parser.parse file
|
110
|
+
else
|
111
|
+
ARGF.each_line do |line|
|
112
|
+
parser.parse line.chomp
|
113
|
+
end
|
114
|
+
end
|
115
|
+
rescue Interrupt
|
116
|
+
exit
|
78
117
|
end
|
79
|
-
log = LogFile::new file, filter, @params
|
80
|
-
log.read
|
81
|
-
log.print_info if @print_info
|
82
|
-
log.print_exception_info if @print_exception_info
|
83
|
-
log.print_exception_entries if @print_exception_entries
|
84
|
-
log.print_entries if @print_log
|
data/lib/sherlog_holmes.rb
CHANGED
@@ -1,4 +1,63 @@
|
|
1
|
+
# The MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2015 Marcelo "Ataxexe" Guimarães <ataxexe@devnull.tools>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'yummi'
|
24
|
+
require 'yaml'
|
25
|
+
|
1
26
|
require_relative 'sherlog_holmes/version'
|
2
|
-
require_relative 'sherlog_holmes/
|
3
|
-
require_relative 'sherlog_holmes/
|
4
|
-
require_relative 'sherlog_holmes/
|
27
|
+
require_relative 'sherlog_holmes/result'
|
28
|
+
require_relative 'sherlog_holmes/entry'
|
29
|
+
require_relative 'sherlog_holmes/filter'
|
30
|
+
require_relative 'sherlog_holmes/parser'
|
31
|
+
|
32
|
+
module Sherlog
|
33
|
+
|
34
|
+
PATTERNS = {}
|
35
|
+
|
36
|
+
def self.load_patterns(file)
|
37
|
+
patterns = YAML::load_file file
|
38
|
+
patterns.each do |id, config|
|
39
|
+
PATTERNS[id.to_sym] = {
|
40
|
+
entry: Regexp::new(config['entry']),
|
41
|
+
exception: Regexp::new(config['exception']),
|
42
|
+
stacktrace: Regexp::new(config['stacktrace'])
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Dir['%s/../conf/patterns/*.yml' % File.dirname(__FILE__)].each do |file|
|
48
|
+
load_patterns file
|
49
|
+
end
|
50
|
+
|
51
|
+
Dir['%s/.sherlog/patterns/*.yml' % ENV['HOME']].each do |file|
|
52
|
+
load_patterns file
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.parser(pattern_id)
|
56
|
+
Parser::new PATTERNS[pattern_id.to_sym]
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.loaded_patterns
|
60
|
+
PATTERNS
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# The MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2015 Marcelo "Ataxexe" Guimarães <ataxexe@devnull.tools>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module Sherlog
|
24
|
+
class Entry
|
25
|
+
|
26
|
+
attr_accessor :time, :level, :category, :origin, :message, :exception, :stacktrace, :raw_content
|
27
|
+
|
28
|
+
def initialize(params = {})
|
29
|
+
@time = params[:time]
|
30
|
+
@level = params[:level]
|
31
|
+
@category = params[:category]
|
32
|
+
@origin = params[:origin]
|
33
|
+
@message = params[:message]
|
34
|
+
@exception = params[:exception]
|
35
|
+
@stacktrace = []
|
36
|
+
end
|
37
|
+
|
38
|
+
def exception?
|
39
|
+
!@exception.nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
def <<(line)
|
43
|
+
@message << $/ << line
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
format = []
|
48
|
+
params = []
|
49
|
+
format << '%s' && params << time if time
|
50
|
+
format << '%s' && params << level.to_s.ljust(7) if level
|
51
|
+
format << '[%s]' && params << category if category
|
52
|
+
format << '(%s)' && params << origin if origin
|
53
|
+
format << '%s' && params << message if message
|
54
|
+
string = format.join(' ') % params
|
55
|
+
([string] + @stacktrace).join($/)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# The MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2015 Marcelo "Ataxexe" Guimarães <ataxexe@devnull.tools>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module Sherlog
|
24
|
+
|
25
|
+
class Filter
|
26
|
+
|
27
|
+
def initialize(&block)
|
28
|
+
@block = block
|
29
|
+
end
|
30
|
+
|
31
|
+
def call(object)
|
32
|
+
accept? object
|
33
|
+
end
|
34
|
+
|
35
|
+
def accept?(object)
|
36
|
+
@block.call object
|
37
|
+
end
|
38
|
+
|
39
|
+
def and(other_filter = nil, &other_block)
|
40
|
+
other_filter ||= Filter::new &other_block
|
41
|
+
Filter::new do |entry|
|
42
|
+
self.accept?(entry) && other_filter.accept?(entry)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def or(other_filter = nil, &other_block)
|
47
|
+
other_filter ||= Filter::new &other_block
|
48
|
+
Filter::new do |entry|
|
49
|
+
self.accept?(entry) || other_filter.accept?(entry)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.expression(expression)
|
54
|
+
Filter::new do |object|
|
55
|
+
wildcard_at_start = expression.start_with? '*'
|
56
|
+
wildcard_at_end = expression.end_with? '*'
|
57
|
+
if wildcard_at_start and wildcard_at_end
|
58
|
+
object.to_s.index expression[1...-1]
|
59
|
+
elsif wildcard_at_start
|
60
|
+
object.to_s.end_with? expression[1..-1]
|
61
|
+
elsif wildcard_at_end
|
62
|
+
object.to_s.start_with? expression[0...-1]
|
63
|
+
else
|
64
|
+
object.to_s == expression.to_s
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.level(expression)
|
70
|
+
Filter::new do |entry|
|
71
|
+
entry.level.to_s == expression.to_s
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.category(expression)
|
76
|
+
Filter::new do |entry|
|
77
|
+
expression(expression).accept? entry.category
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.origin(expression)
|
82
|
+
Filter::new do |entry|
|
83
|
+
expression(expression).accept? entry.origin
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.message(expression)
|
88
|
+
Filter::new do |entry|
|
89
|
+
expression(expression).accept? entry.message
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.exception(expression)
|
94
|
+
Filter::new do |entry|
|
95
|
+
expression(expression).accept? entry.exception
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.exceptions
|
100
|
+
Filter::new do |entry|
|
101
|
+
entry.exception?
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# The MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2015 Marcelo "Ataxexe" Guimarães <ataxexe@devnull.tools>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module Sherlog
|
24
|
+
class Parser
|
25
|
+
|
26
|
+
def initialize(patterns = {}, filter = nil)
|
27
|
+
@filter = filter
|
28
|
+
@patterns = {
|
29
|
+
exception: /^$/,
|
30
|
+
stacktrace: /^$/
|
31
|
+
}.merge patterns
|
32
|
+
@filter ||= filter { |entry| true }
|
33
|
+
@listeners = []
|
34
|
+
end
|
35
|
+
|
36
|
+
def collect
|
37
|
+
result = Result::new
|
38
|
+
on_new_entry do |entry|
|
39
|
+
result << entry
|
40
|
+
end
|
41
|
+
result
|
42
|
+
end
|
43
|
+
|
44
|
+
def on_new_entry(listener = nil, &block)
|
45
|
+
listener ||= block
|
46
|
+
@listeners << listener
|
47
|
+
end
|
48
|
+
|
49
|
+
def filter(filter = nil, &block)
|
50
|
+
@filter = filter if filter
|
51
|
+
@filter = Filter::new &block if block
|
52
|
+
end
|
53
|
+
|
54
|
+
def patterns(config)
|
55
|
+
@patterns.merge! config
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse(input)
|
59
|
+
entry = nil
|
60
|
+
foreach input do |line|
|
61
|
+
try_guess_pattern line unless @patterns[:entry]
|
62
|
+
if @patterns[:entry] =~ line
|
63
|
+
entry_data = Hash[Regexp.last_match.names.map { |k| [k.to_sym, Regexp.last_match[k]] }]
|
64
|
+
notify entry
|
65
|
+
entry = Entry::new entry_data
|
66
|
+
entry.raw_content = line.chomp
|
67
|
+
entry.exception = Regexp.last_match[:exception] if @patterns[:exception] =~ entry.message
|
68
|
+
entry = nil unless @filter.accept? entry
|
69
|
+
else
|
70
|
+
if entry
|
71
|
+
if entry.exception? and @patterns[:stacktrace] =~ line
|
72
|
+
entry.stacktrace << line.chomp
|
73
|
+
else
|
74
|
+
entry << line.chomp
|
75
|
+
end
|
76
|
+
entry.raw_content << $/ << line.chomp
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
notify entry
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def foreach(input, &block)
|
86
|
+
if File.exist? input
|
87
|
+
IO.foreach input, &block
|
88
|
+
else
|
89
|
+
input.each_line &block
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def notify(entry)
|
94
|
+
return unless entry
|
95
|
+
@listeners.each do |listener|
|
96
|
+
listener.call entry
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def try_guess_pattern(line)
|
101
|
+
key, patterns = Sherlog.loaded_patterns.find do |key, patterns|
|
102
|
+
patterns[:entry].match line
|
103
|
+
end
|
104
|
+
patterns ||= {entry: /(?<message>.+)/}
|
105
|
+
@patterns.merge! patterns
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# The MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2015 Marcelo "Ataxexe" Guimarães <ataxexe@devnull.tools>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module Sherlog
|
24
|
+
class Result
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@entries = []
|
28
|
+
end
|
29
|
+
|
30
|
+
def <<(entry)
|
31
|
+
@entries << entry
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def entries(params = {})
|
36
|
+
return @entries.find_all { |entry| params[:filter].accept? entry } if params[:filter]
|
37
|
+
@entries
|
38
|
+
end
|
39
|
+
|
40
|
+
def exceptions
|
41
|
+
entries filter: Filter::exceptions
|
42
|
+
end
|
43
|
+
|
44
|
+
def size
|
45
|
+
@entries.size
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -1,3 +1,25 @@
|
|
1
|
+
# The MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2015 Marcelo "Ataxexe" Guimarães <ataxexe@devnull.tools>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
1
23
|
module Sherlog
|
2
|
-
VERSION = '0.
|
24
|
+
VERSION = '0.2.0'
|
3
25
|
end
|
data/sherlog-holmes.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sherlog-holmes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ataxexe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yummi
|
@@ -53,19 +53,19 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '10.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 3.4.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 3.4.0
|
69
69
|
description:
|
70
70
|
email:
|
71
71
|
- ataxexe@devnull.tools
|
@@ -76,7 +76,9 @@ extra_rdoc_files: []
|
|
76
76
|
files:
|
77
77
|
- ".gitignore"
|
78
78
|
- ".idea/.name"
|
79
|
+
- ".idea/.rakeTasks"
|
79
80
|
- ".idea/compiler.xml"
|
81
|
+
- ".idea/copyright/MIT.xml"
|
80
82
|
- ".idea/copyright/profiles_settings.xml"
|
81
83
|
- ".idea/encodings.xml"
|
82
84
|
- ".idea/misc.xml"
|
@@ -84,15 +86,18 @@ files:
|
|
84
86
|
- ".idea/sherlog-holmes.iml"
|
85
87
|
- ".idea/uiDesigner.xml"
|
86
88
|
- ".idea/vcs.xml"
|
89
|
+
- ".rspec"
|
87
90
|
- Gemfile
|
88
91
|
- LICENSE.txt
|
89
92
|
- README.md
|
90
93
|
- Rakefile
|
91
94
|
- bin/sherlog
|
95
|
+
- conf/patterns/jboss.yml
|
92
96
|
- lib/sherlog_holmes.rb
|
93
|
-
- lib/sherlog_holmes/
|
94
|
-
- lib/sherlog_holmes/
|
95
|
-
- lib/sherlog_holmes/
|
97
|
+
- lib/sherlog_holmes/entry.rb
|
98
|
+
- lib/sherlog_holmes/filter.rb
|
99
|
+
- lib/sherlog_holmes/parser.rb
|
100
|
+
- lib/sherlog_holmes/result.rb
|
96
101
|
- lib/sherlog_holmes/version.rb
|
97
102
|
- sherlog-holmes.gemspec
|
98
103
|
homepage: https://github.com/devnull-tools/sherlog-holmes
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module Sherlog
|
2
|
-
class LogEntry
|
3
|
-
|
4
|
-
attr_accessor :time, :level, :category, :origin, :message, :exception_class
|
5
|
-
|
6
|
-
def initialize(params = {})
|
7
|
-
@time = params[:time]
|
8
|
-
@level = params[:level]
|
9
|
-
@category = params[:category]
|
10
|
-
@origin = params[:origin]
|
11
|
-
@message = params[:message]
|
12
|
-
@stacktrace = []
|
13
|
-
data = /(\w+(\.\w+)+(Exception|Error))/.match @message
|
14
|
-
if data
|
15
|
-
@exception_class = data[1]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def exception?
|
20
|
-
!@exception_class.nil?
|
21
|
-
end
|
22
|
-
|
23
|
-
def <<(line)
|
24
|
-
@stacktrace << line
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_s
|
28
|
-
string = if origin
|
29
|
-
'%s %s [%s] (%s) %s' % [time, level.ljust(7), category, origin, message]
|
30
|
-
else
|
31
|
-
'%s %s [%s] %s' % [time, level.ljust(7), category, message]
|
32
|
-
end
|
33
|
-
([string] + @stacktrace).join($/)
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
module Sherlog
|
2
|
-
class LogFile
|
3
|
-
|
4
|
-
attr_reader :entries, :file
|
5
|
-
|
6
|
-
def initialize(logfile, filter, params = {})
|
7
|
-
@file = logfile
|
8
|
-
@params = {
|
9
|
-
stacktrace: true
|
10
|
-
}.merge params
|
11
|
-
@filter = filter
|
12
|
-
@entries = []
|
13
|
-
@exceptions = {}
|
14
|
-
@map = {}
|
15
|
-
end
|
16
|
-
|
17
|
-
def read
|
18
|
-
# time level category origin message
|
19
|
-
regexp = /([0-9,.:]+)\s+(\w+)\s+\[(\S+)\]\s(\(\S+\))?\s?(.+)/
|
20
|
-
entry = nil
|
21
|
-
IO.foreach(file) do |line|
|
22
|
-
data = regexp.match line.chomp
|
23
|
-
if data
|
24
|
-
entry = LogEntry::new time: data[1],
|
25
|
-
level: data[2],
|
26
|
-
category: data[3],
|
27
|
-
origin: data[4].to_s[1..-1],
|
28
|
-
message: data[5]
|
29
|
-
if @filter.accept? entry
|
30
|
-
@entries << entry
|
31
|
-
if entry.exception?
|
32
|
-
@exceptions[entry.exception_class] ||= []
|
33
|
-
@exceptions[entry.exception_class] << entry
|
34
|
-
end
|
35
|
-
@map[entry.level] ||= {}
|
36
|
-
@map[entry.level][entry.category] ||= []
|
37
|
-
|
38
|
-
@map[entry.level][entry.category] << entry
|
39
|
-
end
|
40
|
-
else
|
41
|
-
entry << line.chomp if entry and @params[:stacktrace]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def print_info(target = $stdout)
|
47
|
-
@map.each do |level, categories|
|
48
|
-
table = Yummi::Table::new
|
49
|
-
table.title = 'Entries for %s level by category' % level
|
50
|
-
table.header = %w(Category Count)
|
51
|
-
table.colorize :category, with: 'bold.white'
|
52
|
-
table.colorize :count, with: 'magenta'
|
53
|
-
categories.sort_by { |k, v| v.size }.each do |category, entries|
|
54
|
-
table << [category, entries.size]
|
55
|
-
end
|
56
|
-
table.print target
|
57
|
-
target.print $/
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def print_entries(target = $stdout)
|
62
|
-
@entries.each do |entry|
|
63
|
-
target.print entry.to_s + $/
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def print_exception_entries(target = $stdout)
|
68
|
-
@entries.each do |entry|
|
69
|
-
target.print entry.to_s + $/ if entry.exception?
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def print_exception_info(target = $stdout)
|
74
|
-
unless @exceptions.empty?
|
75
|
-
table = Yummi::Table::new
|
76
|
-
table.title = 'Exceptions by class'
|
77
|
-
table.header = %w(Class Count)
|
78
|
-
table.colorize :class, with: 'bold.white'
|
79
|
-
table.colorize :count, with: 'magenta'
|
80
|
-
@exceptions.sort_by { |k, v| v.size }.each do |exception_class, entries|
|
81
|
-
table << [exception_class, entries.size]
|
82
|
-
end
|
83
|
-
table.print target
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module Sherlog
|
2
|
-
class LogFilter
|
3
|
-
|
4
|
-
def initialize
|
5
|
-
@filters = []
|
6
|
-
end
|
7
|
-
|
8
|
-
def filter(filter = nil, &block)
|
9
|
-
@filters << filter if filter
|
10
|
-
@filters << block if block
|
11
|
-
end
|
12
|
-
|
13
|
-
def level(expression)
|
14
|
-
filter do |entry|
|
15
|
-
/#{expression}/i.match entry.level
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def category(expression)
|
20
|
-
filter do |entry|
|
21
|
-
/#{expression}/.match entry.category
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def message(expression)
|
26
|
-
filter do |entry|
|
27
|
-
/#{expression}/i.match entry.category
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def exception(expression)
|
32
|
-
filter do |entry|
|
33
|
-
/#{expression}/.match entry.category
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def exceptions
|
38
|
-
self << lambda do |entry|
|
39
|
-
entry.exception?
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def accept?(entry)
|
44
|
-
@filters.all? { |filter| filter.call entry }
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|