summaryrefslogtreecommitdiff
path: root/src/invidious/helpers/logger.cr
blob: e2e50905447d053c6d81edaba5987bf3ae440f1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
enum LogLevel
  All   = 0
  Trace = 1
  Debug = 2
  Info  = 3
  Warn  = 4
  Error = 5
  Fatal = 6
  Off   = 7
end

class Invidious::LogHandler < Kemal::BaseLogHandler
  def initialize(@io : IO = STDOUT, @level = LogLevel::Debug)
  end

  def call(context : HTTP::Server::Context)
    elapsed_time = Time.measure { call_next(context) }
    elapsed_text = elapsed_text(elapsed_time)

    # Default: full path with parameters
    requested_url = context.request.resource

    # Try not to log search queries passed as GET parameters during normal use
    # (They will still be logged if log level is 'Debug' or 'Trace')
    if @level > LogLevel::Debug && (
         requested_url.downcase.includes?("search") || requested_url.downcase.includes?("q=")
       )
      # Log only the path
      requested_url = context.request.path
    end

    info("#{context.response.status_code} #{context.request.method} #{requested_url} #{elapsed_text}")

    context
  end

  def puts(message : String)
    @io << message << '\n'
    @io.flush
  end

  def write(message : String)
    @io << message
    @io.flush
  end

  def set_log_level(level : String)
    @level = LogLevel.parse(level)
  end

  def set_log_level(level : LogLevel)
    @level = level
  end

  {% for level in %w(trace debug info warn error fatal) %}
    def {{level.id}}(message : String)
      if LogLevel::{{level.id.capitalize}} >= @level
        puts("#{Time.utc} [{{level.id}}] #{message}")
      end
    end
  {% end %}

  private def elapsed_text(elapsed)
    millis = elapsed.total_milliseconds
    return "#{millis.round(2)}ms" if millis >= 1

    "#{(millis * 1000).round(2)}µs"
  end
end