Module: Startback::Support::Robustness

Overview

This module provides helper methods for robustness of a software design.

It is included by main Startback abstractions, and can be included by specific software components who needs fine-tuning of monitoring, logging and error handling.

All public methods here follow the following free args parameters:

  1. First (& second) argument(s) form the log message.

    A full log message is a Hash having :op (required), :op_took (optional), and :op_data (optional) keys.

    If a String (or two) are used instead, a log message will be built taking the former as the executer (a class or instance) and the second as a method. ‘{ op: “executer#method” }`

  2. The second (or third) argument should be a Logger instance, a Context, or an instance knowing its context. The best logger is extracted from it and used for actual logging.

Examples:

log(:info, op: "hello", op_data: {foo: 12})    => logged as such on STDOUT
log(:info, "A simple message")                 => { op: "A simple message" } on STDOUT
log(:info, Startback, "hello")                 => { op: "Startback#hello"  } on STDOUT
log(:info, Event.new, "hello")                 => { op: "Event#hello" }      on STDOUT
log(:info, Event.new, "hello", "hello world")  => { op: "Event#hello", op_data: { message: "hello world" } } on STDOUT
log(:info, self, context)                      => { op: "..." } on context's logger or STDOUT
log(:info, self, event)                        => { op: "..." } on event context's logger or STDOUT
...

Defined Under Namespace

Modules: Tools

Instance Method Summary collapse

Instance Method Details

#log(severity, *args) ⇒ Object

Logs a specific message with a given severity.

Severity can be :debug, :info, :warn, :error or :fatal. The args must follow module’s conventions, see above.



103
104
105
# File 'lib/startback/support/robustness.rb', line 103

def log(severity, *args)
  Tools.send(severity, args)
end

#logger_for(arg) ⇒ Object

Returns the natural logger to use for a specific arg



95
96
97
# File 'lib/startback/support/robustness.rb', line 95

def logger_for(arg)
  Tools.logger_for(arg)
end

#monitor(*args, &bl) ⇒ Object

Calls the block and monitors then log its execution time.

The args must follow module’s conventions, see above.



110
111
112
113
114
115
116
117
# File 'lib/startback/support/robustness.rb', line 110

def monitor(*args, &bl)
  result = nil
  took = Benchmark.realtime {
    result = bl.call
  }
  Tools.info(args, op_took: took)
  result
end

#stop_errors(*args, &bl) ⇒ Object

Executes the block without letting errors propagate. Errors are logged, though. Nothing is logged if everything goes fine.

The args must follow module’s conventions, see above.



124
125
126
127
128
129
130
131
132
133
# File 'lib/startback/support/robustness.rb', line 124

def stop_errors(*args, &bl)
  result = nil
  took = Benchmark.realtime {
    result = bl.call
  }
  result
rescue => ex
  Tools.fatal(args, op_took: took, error: ex)
  nil
end

#try_max_times(n, *args, &bl) ⇒ Object

Tries executing the block up to ‘n` times, until an attempt succeeds (then returning the result). Logs the first and last fatal error, if any.

The args must follow module’s conventions, see above.



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/startback/support/robustness.rb', line 140

def try_max_times(n, *args, &bl)
  retried = 0
  took = 0
  begin
    result = nil
    took += Benchmark.realtime {
      result = bl.call
    }
    result
  rescue => ex
    Tools.error(args + [{op_took: took, error: ex}]) if retried == 0
    retried += 1
    if retried < n
      sleep(retried)
      retry
    else
      Tools.fatal(args + [{op_took: took, error: ex}])
      raise
    end
  end
end