Module: Tag

Defined in:
lib/dbg_tags.rb

Overview

Examples:

Usage:


# enabling
# -----------
require 'dbg_tags'

Tag.enable :feature1, :feature2..., featureN: :log, featureO: :val, ...
Tag.enable feature1: :trc, feature2: :val
Tag.enable feature: Tag::TRC
Tag.enable :dtl # enables ALL logging for :generic 
Tag.enable :val # enables val+trc+log+err for :generic only
Tag.enable :trc # enables trc+log+err for :generic only
Tag.enable :log # enables log+err tags for :generic
Tag.enable :err # enables err tags for :generic
Tag.enable # sets :generic to :trc
Tag.enable(...) do ... end
Tag.enable feature: nil
Tag.enable feature: :nil
Tag.enable all: :err    # :all is a default for ALL systems, including :generic
Tag.enable test: :err # switch on paranoia checking
Tag.enable feature: '>=trc'  # make sure at least level trc

# logging 
# -----------
Tag.err 'text', short for Tag.err(:generic) 'text' 
    # :err should be used for fail states and paranoia stuff
Tag.log 'text' # prints very important messages only
Tag.trc 'text' # default level, method entries, for example
Tag.val 'text' # prints more details
Tag.dtl 'text' # likely prints megabytes of details
Tag.err :feature, 'FAILURE'
Tag.log :feature, 'log me'
Tag.trc :feature, 'called method'
Tag.val(:feature) { "text#{expr}" }
Tag.dtl(:feature) { "text#{very complicated expr}" }
Tag.err(:test) { raise 'aaaarg' if complex_paranoia_failure }
Tag.err(:test) { raise 'CANTHAPPEN' if complex_paranoia_failure }

Defined Under Namespace

Classes: GlobalState

Constant Summary collapse

TAG_FEATURE_ALL =

:all overrides the minimum level on ALL tags in the system

:all
TAG_FEATURE_GENERIC =

:generic is the default feature, if left unspecified

:generic
NONE =

lowest level. No output

0
ERR =

level 1. Only error situation should use this

1
LOG =

level 2. Only very important information

2
TRC =

level 3. Mostly used for method entries

3
VAL =

level 4. Mostly used dumping of attribute values

4
DTL =

level 5. Mostly used for exhaustive dumping of attribute values and minor details

5
TAG_DEFAULT_LEVEL =

the default is :trc

TRC
TAG_MAPPING =

nil and :nil will both map to NONE

{ none: NONE, err: ERR, log: LOG, trc: TRC, val: VAL, dtl: DTL, 
  nil: NONE,
  nil => NONE
}

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.no_fiber_local_stateBool? Also known as: no_fiber_local_state?

Returns True if we should store global state inside the Tag class itself.

Returns:

  • (Bool, nil)

    True if we should store global state inside the Tag class itself.



201
202
203
# File 'lib/dbg_tags.rb', line 201

def no_fiber_local_state
  @no_fiber_local_state
end

Class Method Details

.disable_fiber_local_stateObject

shortcut for no_fiber_local_state := true By default fiber local state is enabled but this means that ‘enabling’ of tags in some fiber does not work in others. Or more specific, that changing the Tag state outside of any fiber does not effect any fibers (already) created. Now it is possible to transfer data into the fiber using ‘resume’ but this is a hassle. So: when using threads leave this enabled, as it will cause race conditions. when using fibers, but no threads it is probably convenient to disable it.



307
# File 'lib/dbg_tags.rb', line 307

def disable_fiber_local_state; self.no_fiber_local_state = true end

.dtl(feature = TAG_FEATURE_GENERIC, msg = '', &block) ⇒ Object

See Also:



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/dbg_tags.rb', line 240

TAG_MAPPING.each do |meth, lev|
  next if lev == NONE
  define_method meth do |feature = TAG_FEATURE_GENERIC, msg = '', &msg_block|
    state = global_state
	msg, feature = feature, TAG_FEATURE_GENERIC if String === feature
#STDERR.puts "DEBUGTAG #{meth}. feature=#{feature}, level=#{Tag.level(feature)}, lev=#{lev}"
    return if state.inside? || (state.level(feature) || Tag::NONE) < lev
	# either msg OR msg_block must be set
	if msg_block
      prev_inside = state.inside?
	  begin
        state.inside = true
 msg = msg_block.call 
	  ensure
        state.inside = prev_inside
	  end
	end
    if msg
      c = caller[0]
  #STDERR.puts "DEBUGTAG c[#{idx}] = #{c}, caller[1]=#{caller[1]}, caller[2]=#{caller[2]}"
      label = c[/\w+\.rb:\d+:in `[^']+'/]&.sub(/in `([^']+)'/, '\1:') ||
              c[/\w+\.rb:\d+:/] ||
              c[/[^:\/]+:\d+:/] || 
              c
      state.stream.print "#{label} #{msg}\n"
    end
  end # Tag.err, Tag.log, Tag.trc, Tag.val, Tag.dtl
end

.enableObject



273
# File 'lib/dbg_tags.rb', line 273

def enable(...); global_state.enable(...); end

.enable_fiber_local_stateObject

shortcut for no_fiber_local_state := false For rspec use mostly.



311
# File 'lib/dbg_tags.rb', line 311

def enable_fiber_local_state; self.no_fiber_local_state = false end

.enabled{Symbol=>0..5} Also known as: state

Returns Keys are the features.

Returns:

  • ({Symbol=>0..5})

    Keys are the features



279
# File 'lib/dbg_tags.rb', line 279

def enabled; global_state.enabled; end

.enabled?(feature) ⇒ bool

Returns Reflects explicit enable calls only. The :all feature is IGNORED.

Parameters:

  • feature (Symbol)

Returns:

  • (bool)

    Reflects explicit enable calls only. The :all feature is IGNORED



296
# File 'lib/dbg_tags.rb', line 296

def enabled? feature; (global_state.enabled[feature] || NONE) > NONE; end

.err(feature = TAG_FEATURE_GENERIC, msg = '', &block) ⇒ Object

See Also:



# File 'lib/dbg_tags.rb', line 228

.global_stateGlobalState

Returns Either fiber local data (default) or truly global.

Returns:

  • (GlobalState)

    Either fiber local data (default) or truly global.



209
210
211
212
213
214
215
216
# File 'lib/dbg_tags.rb', line 209

def global_state
  if @no_fiber_local_state # testing undefined ivar here. But no warnings... That is good,
      # at least for performance
    @global_state ||= GlobalState.new
  else
    Thread.current[:dbg_tags_global_state] ||= GlobalState.new
  end
end

.inside?Boolean

inside? -> true if we are currently executing a block in err/log/trc/val or dtl.

Returns:

  • (Boolean)


270
# File 'lib/dbg_tags.rb', line 270

def inside?; global_state.inside?; end

.level(feature) ⇒ 0..5

2023-08-14 no longer returns nil

Parameters:

  • feature (Symbol)

Returns:

  • (0..5)

    Current effective level for feature.



292
# File 'lib/dbg_tags.rb', line 292

def level feature; global_state.level feature; end

.log(feature = TAG_FEATURE_GENERIC, msg = '', &block) ⇒ Object

See Also:



# File 'lib/dbg_tags.rb', line 231

.restore_stateObject



276
# File 'lib/dbg_tags.rb', line 276

def restore_state(...); global_state.restore_state(...); end

.streamIO

Returns By default this is STDERR.

Returns:

  • (IO)

    By default this is STDERR



283
# File 'lib/dbg_tags.rb', line 283

def stream; global_state.stream; end

.stream=(val) ⇒ Object

Override the output stream.

Parameters:

  • val (IO)


287
# File 'lib/dbg_tags.rb', line 287

def stream= val; global_state.stream = val; end

.trc(feature = TAG_FEATURE_GENERIC, msg = '', &block) ⇒ Object

Note:

feature and msg can be switched

The call is silently ignored if called from inside another Tag block (likely a sign of a stack overflow in process). The call is silently ignored if the current tag level is too low. For trc it should be trc or val or dtl to actually print something.

Parameters:

  • feature (Symbol, nil) (defaults to: TAG_FEATURE_GENERIC)

    Subsystem to print logging for. Fully dynamic/free

  • msg (String, nil) (defaults to: '')
  • block (Proc, nil)

    If set the result overrides and msg passed.



# File 'lib/dbg_tags.rb', line 218

.use_fiber_local_state?Bool

in each fiber/thread of the application.

Returns:

  • (Bool)

    True (the default) if we should store global state



206
# File 'lib/dbg_tags.rb', line 206

def use_fiber_local_state?; !no_fiber_local_state? end

.val(feature = TAG_FEATURE_GENERIC, msg = '', &block) ⇒ Object

See Also:



# File 'lib/dbg_tags.rb', line 234