Skip to content
Kward Search API index

Class: Kward::Hooks::AuditLog

Inherits:
Object
  • Object
show all
Defined in:
lib/kward/hooks/audit_log.rb

Overview

Append-only JSONL audit log for lifecycle hook activity.

Constant Summary collapse

DEFAULT_MAX_BYTES =
10 * 1024 * 1024

Instance Method Summary collapse

Constructor Details

#initialize(path: nil, config_path: ConfigFiles.config_path, max_bytes: DEFAULT_MAX_BYTES, clock: Time, monotonic_clock: Process, error_output: $stderr) ⇒ AuditLog

Returns a new instance of AuditLog.



14
15
16
17
18
19
20
21
22
23
# File 'lib/kward/hooks/audit_log.rb', line 14

def initialize(path: nil, config_path: ConfigFiles.config_path, max_bytes: DEFAULT_MAX_BYTES, clock: Time, monotonic_clock: Process, error_output: $stderr)
  @path = path
  @config_path = config_path
  @max_bytes = max_bytes.to_i.positive? ? max_bytes.to_i : DEFAULT_MAX_BYTES
  @clock = clock
  @monotonic_clock = monotonic_clock
  @error_output = error_output
  @mutex = Mutex.new
  @warned = false
end

Instance Method Details

#duration_ms(started_at) ⇒ Object



29
30
31
# File 'lib/kward/hooks/audit_log.rb', line 29

def duration_ms(started_at)
  ((monotonic_now - started_at.to_f) * 1000).round(1)
end

#log_handler(event:, handler:, decision:, duration_ms: nil) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/kward/hooks/audit_log.rb', line 33

def log_handler(event:, handler:, decision:, duration_ms: nil)
  write_record(
    "kind" => "handler",
    "event_id" => event.id,
    "event" => event.name,
    "phase" => event.phase,
    "hook_id" => handler.id,
    "source" => handler.source,
    "decision" => decision.decision,
    "message" => redact_string(decision.message),
    "duration_ms" => duration_ms,
    "payload_keys" => safe_keys(event.payload),
    "modified_keys" => decision.modify? ? safe_keys(decision.payload) : []
  )
end

#log_result(event:, result:) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/kward/hooks/audit_log.rb', line 49

def log_result(event:, result:)
  write_record(
    "kind" => "result",
    "event_id" => event.id,
    "event" => event.name,
    "phase" => event.phase,
    "decision" => result.decision.decision,
    "message" => redact_string(result.decision.message),
    "handler_count" => result.decisions.length,
    "warnings" => result.warnings.map { |warning| redact_string(warning) },
    "messages" => result.messages.map { |message| redact_string(message) },
    "payload_keys" => safe_keys(result.payload)
  )
end

#monotonic_nowObject



25
26
27
# File 'lib/kward/hooks/audit_log.rb', line 25

def monotonic_now
  @monotonic_clock.clock_gettime(Process::CLOCK_MONOTONIC)
end