Class: Puppet::Util::Log

Inherits:
Object show all
Extended by:
Puppet::Util, ClassGen
Includes:
Puppet::Util, Tagging
Defined in:
lib/vendor/puppet/util/log.rb

Overview

Pass feedback to the user. Log levels are modeled after syslog’s, and it is expected that that will be the most common log destination. Supports multiple destinations, one of which is a remote server.

Defined Under Namespace

Classes: Destination

Constant Summary

Constants included from Puppet::Util

AbsolutePathPosix, AbsolutePathWindows

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Puppet::Util

absolute_path?, activerecord_version, benchmark, binread, chuser, classproxy, execfail, execpipe, execute, execute_posix, execute_windows, logmethods, memory, path_to_uri, proxy, replace_file, safe_posix_fork, symbolize, symbolizehash, symbolizehash!, synchronize_on, thinmark, threadlock, uri_to_path, wait_for_output, which, withumask

Methods included from POSIX

#get_posix_field, #gid, #idfield, #methodbyid, #methodbyname, #search_posix_field, #uid

Methods included from ClassGen

genclass, genmodule, rmclass

Methods included from MethodHelper

#requiredopts, #set_options, #symbolize_options

Methods included from Tagging

#tag, #tagged?, #tags, #tags=

Constructor Details

#initialize(args) ⇒ Log

Returns a new instance of Log.



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/vendor/puppet/util/log.rb', line 212

def initialize(args)
  self.level = args[:level]
  self.message = args[:message]
  self.source = args[:source] || "Puppet"

  @time = Time.now

  if tags = args[:tags]
    tags.each { |t| self.tag(t) }
  end

  [:file, :line].each do |attr|
    next unless value = args[attr]
    send(attr.to_s + "=", value)
  end

  Log.newmessage(self)
end

Class Attribute Details

.desttypesObject (readonly)

Returns the value of attribute desttypes.



44
45
46
# File 'lib/vendor/puppet/util/log.rb', line 44

def desttypes
  @desttypes
end

Instance Attribute Details

#fileObject

Returns the value of attribute file.



209
210
211
# File 'lib/vendor/puppet/util/log.rb', line 209

def file
  @file
end

#levelObject

Returns the value of attribute level.



210
211
212
# File 'lib/vendor/puppet/util/log.rb', line 210

def level
  @level
end

#lineObject

Returns the value of attribute line.



209
210
211
# File 'lib/vendor/puppet/util/log.rb', line 209

def line
  @line
end

#messageObject

Returns the value of attribute message.



210
211
212
# File 'lib/vendor/puppet/util/log.rb', line 210

def message
  @message
end

#remoteObject

Returns the value of attribute remote.



209
210
211
# File 'lib/vendor/puppet/util/log.rb', line 209

def remote
  @remote
end

#sourceObject

Returns the value of attribute source.



209
210
211
# File 'lib/vendor/puppet/util/log.rb', line 209

def source
  @source
end

#timeObject

Returns the value of attribute time.



209
210
211
# File 'lib/vendor/puppet/util/log.rb', line 209

def time
  @time
end

Class Method Details

.autoflush=(v) ⇒ Object



71
72
73
74
75
# File 'lib/vendor/puppet/util/log.rb', line 71

def Log.autoflush=(v)
  @destinations.each do |type, dest|
    dest.autoflush = v if dest.respond_to?(:autoflush=)
  end
end

.close(destination) ⇒ Object

Reset log to basics. Basically just flushes and closes files and undefs other objects.



49
50
51
52
53
54
55
# File 'lib/vendor/puppet/util/log.rb', line 49

def Log.close(destination)
  if @destinations.include?(destination)
    @destinations[destination].flush if @destinations[destination].respond_to?(:flush)
    @destinations[destination].close if @destinations[destination].respond_to?(:close)
    @destinations.delete(destination)
  end
end

.close_allObject

Raises:



57
58
59
60
61
62
# File 'lib/vendor/puppet/util/log.rb', line 57

def self.close_all
  destinations.keys.each { |dest|
    close(dest)
  }
  raise Puppet::DevError.new("Log.close_all failed to close #{@destinations.keys.inspect}") if !@destinations.empty?
end

.create(hash) ⇒ Object

Create a new log message. The primary role of this method is to avoid creating log messages below the loglevel.

Raises:



79
80
81
82
83
# File 'lib/vendor/puppet/util/log.rb', line 79

def Log.create(hash)
  raise Puppet::DevError, "Logs require a level" unless hash.include?(:level)
  raise Puppet::DevError, "Invalid log level #{hash[:level]}" unless @levels.index(hash[:level])
  @levels.index(hash[:level]) >= @loglevel ? Puppet::Util::Log.new(hash) : nil
end

.destinationsObject



85
86
87
# File 'lib/vendor/puppet/util/log.rb', line 85

def Log.destinations
  @destinations
end

.eachlevelObject

Yield each valid level in turn



90
91
92
# File 'lib/vendor/puppet/util/log.rb', line 90

def Log.eachlevel
  @levels.each { |level| yield level }
end

.flushObject

Flush any log destinations that support such operations.



65
66
67
68
69
# File 'lib/vendor/puppet/util/log.rb', line 65

def Log.flush
  @destinations.each { |type, dest|
    dest.flush if dest.respond_to?(:flush)
  }
end

.flushqueueObject



165
166
167
168
169
170
171
# File 'lib/vendor/puppet/util/log.rb', line 165

def Log.flushqueue
  return unless @destinations.size >= 1
  @queued.each do |msg|
    Log.newmessage(msg)
  end
  @queued.clear
end

.levelObject

Return the current log level.



95
96
97
# File 'lib/vendor/puppet/util/log.rb', line 95

def Log.level
  @levels[@loglevel]
end

.level=(level) ⇒ Object

Set the current log level.

Raises:



100
101
102
103
104
105
106
# File 'lib/vendor/puppet/util/log.rb', line 100

def Log.level=(level)
  level = level.intern unless level.is_a?(Symbol)

  raise Puppet::DevError, "Invalid loglevel #{level}" unless @levels.include?(level)

  @loglevel = @levels.index(level)
end

.levelsObject



108
109
110
# File 'lib/vendor/puppet/util/log.rb', line 108

def Log.levels
  @levels.dup
end

.newdestination(dest) ⇒ Object

Create a new log destination.

Raises:



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/vendor/puppet/util/log.rb', line 113

def Log.newdestination(dest)
  # Each destination can only occur once.
  if @destinations.find { |name, obj| obj.name == dest }
    return
  end

  name, type = @desttypes.find do |name, klass|
    klass.match?(dest)
  end

  if type.respond_to?(:suitable?) and not type.suitable?(dest)
    return
  end

  raise Puppet::DevError, "Unknown destination type #{dest}" unless type

  begin
    if type.instance_method(:initialize).arity == 1
      @destinations[dest] = type.new(dest)
    else
      @destinations[dest] = type.new
    end
    flushqueue
    @destinations[dest]
  rescue => detail
    puts detail.backtrace if Puppet[:debug]

    # If this was our only destination, then add the console back in.
    newdestination(:console) if @destinations.empty? and (dest != :console and dest != "console")
  end
end

.newdesttype(name, options = {}, &block) ⇒ Object

Create a new destination type.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/vendor/puppet/util/log.rb', line 18

def self.newdesttype(name, options = {}, &block)

  dest = genclass(
    name,
    :parent     => Puppet::Util::Log::Destination,
    :prefix     => "Dest",
    :block      => block,
    :hash       => @desttypes,
    :attributes => options
  )
  dest.match(dest.name)

  dest
end

.newmessage(msg) ⇒ Object

Route the actual message. FIXME There are lots of things this method should do, like caching and a bit more. It’s worth noting that there’s a potential for a loop here, if the machine somehow gets the destination set as itself.



149
150
151
152
153
154
155
156
157
158
159
# File 'lib/vendor/puppet/util/log.rb', line 149

def Log.newmessage(msg)
  return if @levels.index(msg.level) < @loglevel

  queuemessage(msg) if @destinations.length == 0

  @destinations.each do |name, dest|
    threadlock(dest) do
      dest.handle(msg)
    end
  end
end

.queuemessage(msg) ⇒ Object



161
162
163
# File 'lib/vendor/puppet/util/log.rb', line 161

def Log.queuemessage(msg)
  @queued.push(msg)
end

.reopenObject

Reopen all of our logs.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/vendor/puppet/util/log.rb', line 178

def Log.reopen
  Puppet.notice "Reopening log files"
  types = @destinations.keys
  @destinations.each { |type, dest|
    dest.close if dest.respond_to?(:close)
  }
  @destinations.clear
  # We need to make sure we always end up with some kind of destination
  begin
    types.each { |type|
      Log.newdestination(type)
    }
  rescue => detail
    if @destinations.empty?
      Log.setup_default
      Puppet.err detail.to_s
    end
  end
end

.sendlevel?(level) ⇒ Boolean

Returns:

  • (Boolean)


173
174
175
# File 'lib/vendor/puppet/util/log.rb', line 173

def Log.sendlevel?(level)
  @levels.index(level) >= @loglevel
end

.setup_defaultObject



198
199
200
201
202
# File 'lib/vendor/puppet/util/log.rb', line 198

def self.setup_default
  Log.newdestination(
    (Puppet.features.syslog?   ? :syslog   :
    (Puppet.features.eventlog? ? :eventlog : Puppet[:puppetdlog])))
end

.validlevel?(level) ⇒ Boolean

Is the passed level a valid log level?

Returns:

  • (Boolean)


205
206
207
# File 'lib/vendor/puppet/util/log.rb', line 205

def self.validlevel?(level)
  @levels.include?(level)
end

Instance Method Details

#to_reportObject



263
264
265
# File 'lib/vendor/puppet/util/log.rb', line 263

def to_report
  "#{time} #{source} (#{level}): #{to_s}"
end

#to_sObject



267
268
269
# File 'lib/vendor/puppet/util/log.rb', line 267

def to_s
  message
end