logtrend 0.9.20101208165234 → 0.9.20101209201344

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 (2) hide show
  1. data/lib/logtrend.rb +89 -46
  2. metadata +4 -4
@@ -5,67 +5,85 @@ require 'rrd'
5
5
  require 'logger'
6
6
  require 'erb'
7
7
 
8
+ # A Ruby module that uses RRD (http://www.mrtg.org/rrdtool/) to generate graphs for trending data from log files.
9
+ #
10
+ # logtrend tails a log file and matches lines one by one, sending matched counters to RRD as appropriate.
8
11
  module LogTrend
9
12
  class Base
10
13
  # This sets the directory where graphs should be stored.
11
14
  attr_accessor :graphs_dir
15
+
12
16
  # This sets the directory where your RRD files will rest.
13
17
  attr_accessor :rrd_dir
14
-
15
- def initialize
16
- @graphs_dir = '.'
17
- @rrd_dir = '.'
18
- @trends = {}
19
- @graphs = []
20
- @logger = Logger.new(STDERR)
21
- @logger.level = ($DEBUG and Logger::DEBUG or Logger::WARN)
22
-
23
- @template = ERB.new <<-EOF
24
- <html>
25
- <head>
26
- <title>logtrend</title>
27
- </head>
28
- <body>
29
- <% @graphs.each do |graph| %>
30
- <img src='<%=graph.name%>.png' />
31
- <% end %>
32
- </body>
33
- </html>
34
- EOF
18
+
19
+ # This sets the logger to use. Must be something that behaves like a Logger object.
20
+ attr_accessor :logger
21
+
22
+ # This sets the HTML file template for the generated index.html file.
23
+ # The String here will pass through ERB, with self being set as the binding.
24
+ #
25
+ # The default generates a simple HTML file that loads one IMG tag per graph.
26
+ attr_accessor :template
27
+
28
+ # Defines the amount of time between each updates, given in seconds. Default value is 60 seconds.
29
+ #
30
+ # From the rrdcreate(2) manual page:
31
+ #
32
+ # Specifies the base interval in seconds with which data will be fed into the RRD.
33
+ #
34
+ #
35
+ # @see http://www.mrtg.org/rrdtool/doc/rrdcreate.en.html
36
+ attr_accessor :step
37
+
38
+ # Defines the amount of time between updates that will mark a value unknown.
39
+ #
40
+ # From the rrdcreate(2) manual page:
41
+ #
42
+ # heartbeat defines the maximum number of seconds that may pass between two updates of this data source before the value of the data source is assumed to be *UNKNOWN*.
43
+ #
44
+ # @see http://www.mrtg.org/rrdtool/doc/rrdcreate.en.html
45
+ attr_accessor :heartbeat
46
+
47
+ def initialize(options={})
48
+ set_defaults
49
+
50
+ options.each do |key, val|
51
+ send("#{key}=", val)
52
+ end
35
53
  end
36
54
 
37
55
  def add_trend(name, &block)
38
- throw "D'oh! No block." unless block_given?
56
+ raise ArgumentError, "D'oh! No block." unless block_given?
39
57
  @trends[name] = block
40
58
  end
41
-
59
+
42
60
  def add_graph(name, &block)
43
- throw "D'oh! No block." unless block_given?
61
+ raise ArgumentError, "D'oh! No block." unless block_given?
44
62
  graph = Graph.new(name)
45
63
  yield graph
46
64
  @graphs << graph
47
65
  end
48
-
66
+ #
49
67
  # This is the preferred entry point.
50
- def self.run(logfile, &block)
68
+ def self.run(logfile, options={}, &block)
51
69
  throw "D'oh! No block." unless block_given?
52
- l = Base.new
70
+ l = Base.new(options)
53
71
  yield l
54
72
  l.run logfile
55
73
  end
56
74
 
57
75
  def run(logfile)
58
76
  counters = reset_counters
59
-
60
- EventMachine.run do
61
- EventMachine::add_periodic_timer(1.minute) do
77
+
78
+ EventMachine.run do
79
+ EventMachine::add_periodic_timer(step) do
62
80
  @logger.debug "#{Time.now} #{counters.inspect}"
63
- counters.each {|name, value| update_rrd(name, value)}
81
+ counters.each {|name, value| update_rrd(name, value)}
64
82
  @graphs.each {|graph| build_graph(graph)}
65
83
  build_page
66
84
  counters = reset_counters
67
85
  end
68
-
86
+
69
87
  EventMachine::file_tail(logfile) do |filetail, line|
70
88
  @trends.each do |name, block|
71
89
  counters[name] += 1 if block.call(line)
@@ -76,7 +94,7 @@ module LogTrend
76
94
  end
77
95
 
78
96
  private
79
-
97
+
80
98
  def reset_counters
81
99
  counters = {}
82
100
  @trends.keys.each do |k|
@@ -84,19 +102,19 @@ module LogTrend
84
102
  end
85
103
  counters
86
104
  end
87
-
105
+
88
106
  def update_rrd(name, value)
89
107
  file_name = File.join(@rrd_dir,"#{name}.rrd")
90
108
  rrd = RRD::Base.new(file_name)
91
- if !File.exists?(file_name)
92
- rrd.create :start => Time.now - 10.seconds, :step => 1.minutes do
93
- datasource "#{name}_count", :type => :gauge, :heartbeat => 5.minutes, :min => 0, :max => :unlimited
109
+ if !File.file?(file_name)
110
+ rrd.create :start => Time.now - 10.seconds, :step => step do
111
+ datasource "#{name}_count", :type => :gauge, :heartbeat => heartbeat, :min => 0, :max => :unlimited
94
112
  archive :average, :every => 5.minutes, :during => 1.year
95
113
  end
96
114
  end
97
115
  rrd.update Time.now, value
98
116
  end
99
-
117
+
100
118
  def build_graph(graph)
101
119
  rrd_dir = @rrd_dir
102
120
  RRD.graph File.join(@graphs_dir,"#{graph.name}.png"), :title => graph.name, :width => 800, :height => 250, :color => ["FONT#000000", "BACK#FFFFFF"] do
@@ -104,35 +122,60 @@ module LogTrend
104
122
  if point.style == :line
105
123
  line File.join(rrd_dir,"#{point.name}.rrd"), "#{point.name}_count" => :average, :color => point.color, :label => point.name.to_s
106
124
  elsif point.style == :area
107
- area File.join(rrd_dir,"#{point.name}.rrd"), "#{point.name}_count" => :average, :color => point.color, :label => point.name.to_s
125
+ area File.join(rrd_dir,"#{point.name}.rrd"), "#{point.name}_count" => :average, :color => point.color, :label => point.name.to_s
108
126
  end
109
127
  end
110
128
  end
111
129
  end
112
-
130
+
113
131
  def build_page
114
132
  file_name = File.join(@graphs_dir,'index.html')
115
133
  File.open(file_name, "w") do |f|
116
134
  f << @template.result(binding)
117
135
  end
118
136
  end
119
-
137
+
138
+ def set_defaults
139
+ @graphs_dir = '.'
140
+ @rrd_dir = '.'
141
+ @trends = {}
142
+ @graphs = []
143
+ @logger = Logger.new(STDERR)
144
+ @logger.level = ($DEBUG and Logger::DEBUG or Logger::WARN)
145
+
146
+ @step = 1.minute
147
+ @heartbeat = 5.minutes
148
+
149
+ @template = ERB.new <<-EOF
150
+ <html>
151
+ <head>
152
+ <title>logtrend</title>
153
+ </head>
154
+ <body>
155
+ <% @graphs.each do |graph| %>
156
+ <img src='<%=graph.name%>.png' />
157
+ <% end %>
158
+ </body>
159
+ </html>
160
+ EOF
161
+ end
162
+ private :set_defaults
120
163
  end
121
164
 
122
165
  class Graph
123
-
166
+
124
167
  attr_reader :points
125
168
  attr_reader :name
126
-
169
+
127
170
  def initialize(name)
128
171
  @name = name
129
172
  @points = []
130
173
  end
131
-
174
+
132
175
  def add_point(style,name,color)
133
- @points << GraphPoint.new(style, name, color)
176
+ @points << GraphPoint.new(style, name, color)
134
177
  end
135
178
  end
136
179
 
137
180
  GraphPoint = Struct.new(:style, :name, :color)
138
- end
181
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logtrend
3
3
  version: !ruby/object:Gem::Version
4
- hash: 40202416330463
4
+ hash: 40202418402747
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 20101208165234
10
- version: 0.9.20101208165234
9
+ - 20101209201344
10
+ version: 0.9.20101209201344
11
11
  platform: ruby
12
12
  authors:
13
13
  - Michael Gorsuch
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-08 00:00:00 -05:00
18
+ date: 2010-12-09 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency