Class: Lumberjack::Template

Inherits:
Object
  • Object
show all
Defined in:
lib/lumberjack/template.rb

Overview

A flexible template system for converting log entries into formatted strings. Templates use mustache style placeholders to create customizable log output formats.

The template system supports the following built-in placeholders:

  • {{time}} - The log entry timestamp

  • {{severity}} - The severity level (DEBUG, INFO, WARN, ERROR, FATAL). The severity can also be formatted in a variety of ways with an optional format specifier. Supported formats include:

    • {{severity(padded)}} - Right padded so that all values are five characters

    • {{severity(char)}} - Single character representation (D, I, W, E, F)

    • {{severity(emoji)}} - Emoji representation

    • {{severity(level)}} - Numeric level representation

  • {{progname}} - The program name that generated the entry

  • {{pid}} - The process ID

  • {{message}} - The main log message content

  • {{attributes}} - All custom attributes formatted as key:value pairs

Custom attribute placeholders can also be put in the double bracket placeholders. Any attributes explicitly added to the template in their own placeholder will be removed from the general list of attributes.

Examples:

Basic template usage

template = Lumberjack::Template.new("[{{time}} {{severity}}] {{message}}")
# Output: [2023-08-21T10:30:15.123 INFO] User logged in

Multi-line message formatting

template = Lumberjack::Template.new(
  "[{{time}} {{severity}}] {{message}}",
  additional_lines: "\n    | {{message}}"
)
# Output:
# [2023-08-21T10:30:15.123 INFO] First line
#     | Second line
#     | Third line

Custom attribute placeholders

# The user_id attribute will be put before the message instead of with the rest of the attributes.
template = Lumberjack::Template.new("[{{time}} {{severity}}] (usr:{{user_id}} {{message}} -- {{attributes}})")

Direct Known Subclasses

StandardFormatterTemplate

Defined Under Namespace

Classes: StandardFormatterTemplate

Constant Summary collapse

DEFAULT_FIRST_LINE_TEMPLATE =
"[{{time}} {{severity(padded)}} {{progname}}({{pid}})] {{message}} {{attributes}}"
STDLIB_FIRST_LINE_TEMPLATE =
"{{severity(char)}}, [{{time}} {{pid}}] {{severity(padded)}} -- {{progname}}: {{message}} {{attributes}}"
DEFAULT_ADDITIONAL_LINES_TEMPLATE =
"#{Lumberjack::LINE_SEPARATOR}> {{message}}"
DEFAULT_ATTRIBUTE_FORMAT =
"[%s:%s]"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(first_line = nil, additional_lines: nil, time_format: nil, attribute_format: nil, colorize: false) ⇒ Template

Create a new template with customizable formatting options. The template supports different formatting for single-line and multi-line messages, custom time formatting, and configurable attribute display.

Parameters:

  • first_line (String, nil) (defaults to: nil)

    Template for formatting the first line of messages. Defaults to [{{ time }} {{ severity(padded) }} {{ progname }}({{ pid }})] {{ message }} {{ attributes }}

  • additional_lines (String, nil) (defaults to: nil)

    Template for formatting additional lines in multi-line messages. Defaults to \n> {{ message }}

  • time_format (String, Symbol, nil) (defaults to: nil)

    Time formatting specification. Can be:

    • A strftime format string (e.g., “%Y-%m-%d %H:%M:%S”)

    • :milliseconds for ISO format with millisecond precision (default)

    • :microseconds for ISO format with microsecond precision

  • attribute_format (String, nil) (defaults to: nil)

    Printf-style format for individual attributes. Must contain exactly two %s placeholders for name and value. Defaults to “[%s:%s]”

  • colorize (Boolean) (defaults to: false)

    Whether to colorize the log entry based on severity (default: false)

Raises:

  • (ArgumentError)

    If attribute_format doesn’t contain exactly two %s placeholders



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/lumberjack/template.rb', line 133

def initialize(first_line = nil, additional_lines: nil, time_format: nil, attribute_format: nil, colorize: false)
  first_line ||= DEFAULT_FIRST_LINE_TEMPLATE
  first_line = "#{first_line.chomp}#{Lumberjack::LINE_SEPARATOR}"
  if !first_line.include?("{{") && first_line.match?(V1_PLACEHOLDER_PATTERN)
    Utils.deprecated("Template.v1", "Templates now use {{placeholder}} instead of :placeholder and :tags has been replaced with {{attributes}}.") do
      @first_line_template, @first_line_attributes = compile_v1(first_line)
    end
  else
    @first_line_template, @first_line_attributes = compile(first_line)
  end

  additional_lines ||= DEFAULT_ADDITIONAL_LINES_TEMPLATE
  if !additional_lines.include?("{{") && additional_lines.match?(V1_PLACEHOLDER_PATTERN)
    Utils.deprecated("Template.v1", "Templates now use {{placeholder}} instead of :placeholder and :tags has been replaced with {{attributes}}.") do
      @additional_line_template, @additional_line_attributes = compile_v1(additional_lines)
    end
  else
    @additional_line_template, @additional_line_attributes = compile(additional_lines)
  end

  @attribute_template = attribute_format || DEFAULT_ATTRIBUTE_FORMAT
  unless @attribute_template.scan("%s").size == 2
    raise ArgumentError.new("attribute_format must be a printf template with exactly two '%s' placeholders")
  end

  # Formatting the time is relatively expensive, so only do it if it will be used
  @template_include_time = "#{@first_line_template} #{@additional_line_template}".include?("%1$s")
  self.datetime_format = (time_format || :milliseconds)

  @colorize = colorize
end

Class Method Details

.colorize_entry(formatted_string, entry) ⇒ Object



109
110
111
112
113
114
# File 'lib/lumberjack/template.rb', line 109

def colorize_entry(formatted_string, entry)
  color_start = entry.severity_data.terminal_color
  formatted_string.split(Lumberjack::LINE_SEPARATOR).collect do |line|
    "\e7#{color_start}#{line}\e8"
  end.join(Lumberjack::LINE_SEPARATOR)
end

Instance Method Details

#call(entry) ⇒ String

Convert a log entry into a formatted string using the template. This method handles both single-line and multi-line messages, applying the appropriate templates and performing placeholder substitution.

Parameters:

Returns:

  • (String)

    The formatted log entry string



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/lumberjack/template.rb', line 195

def call(entry)
  return entry unless entry.is_a?(LogEntry)

  first_line = entry.message.to_s
  additional_lines = nil
  if first_line.include?(Lumberjack::LINE_SEPARATOR)
    additional_lines = first_line.split(Lumberjack::LINE_SEPARATOR)
    first_line = additional_lines.shift
  end

  formatted_time = @time_formatter.call(entry.time) if @template_include_time
  severity = entry.severity_data
  format_args = [
    formatted_time,
    severity.label,
    severity.padded_label,
    severity.char,
    severity.emoji,
    severity.level,
    entry.progname,
    entry.pid,
    first_line
  ]
  append_attribute_args!(format_args, entry.attributes, @first_line_attributes)
  message = (@first_line_template % format_args)

  if additional_lines && !additional_lines.empty?
    format_args.slice!(9, format_args.size)
    append_attribute_args!(format_args, entry.attributes, @additional_line_attributes)

    message_length = message.length
    message.chomp!(Lumberjack::LINE_SEPARATOR)
    chomped = message.length != message_length

    additional_lines.each do |line|
      format_args[8] = line
      line_message = @additional_line_template % format_args
      message << line_message
    end

    message << Lumberjack::LINE_SEPARATOR if chomped
  end

  message = Template.colorize_entry(message, entry) if @colorize

  message
end

#datetime_formatString

Get the current datetime format string used for timestamp formatting.

Returns:

  • (String)

    The strftime format string currently in use



185
186
187
# File 'lib/lumberjack/template.rb', line 185

def datetime_format
  @time_formatter.format
end

#datetime_format=(format) ⇒ void

This method returns an undefined value.

Set the datetime format used for timestamp formatting in the template. This method accepts both strftime format strings and symbolic shortcuts.

Parameters:

  • format (String, Symbol)

    The datetime format specification:

    • String: A strftime format pattern (e.g., “%Y-%m-%d %H:%M:%S”)

    • :milliseconds: ISO format with millisecond precision (YYYY-MM-DDTHH:MM:SS.sss)

    • :microseconds: ISO format with microsecond precision (YYYY-MM-DDTHH:MM:SS.ssssss)



173
174
175
176
177
178
179
180
# File 'lib/lumberjack/template.rb', line 173

def datetime_format=(format)
  if format == :milliseconds
    format = MILLISECOND_TIME_FORMAT
  elsif format == :microseconds
    format = MICROSECOND_TIME_FORMAT
  end
  @time_formatter = Formatter::DateTimeFormatter.new(format)
end