logtrend 0.9.20101208165234 → 0.9.20101209201344

Sign up to get free protection for your applications and to get access to all the features.
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