apiVersion: v1
kind: ConfigMap
metadata:
  name: loki-gateway
  namespace: loki
  labels:
    helm.sh/chart: loki-17.1.0
    app.kubernetes.io/name: loki
    app.kubernetes.io/instance: loki
    app.kubernetes.io/version: "3.7.2"
    app.kubernetes.io/component: gateway
data:
  nginx.conf: "worker_processes  5;  ## Default: 1\nerror_log  /dev/stderr;\npid        /tmp/nginx.pid;\nworker_rlimit_nofile 8192;\n\nevents {\n  worker_connections  4096;  ## Default: 1024\n}\n\nhttp {\n  client_body_temp_path /tmp/client_temp;\n  proxy_temp_path       /tmp/proxy_temp_path;\n  fastcgi_temp_path     /tmp/fastcgi_temp;\n  uwsgi_temp_path       /tmp/uwsgi_temp;\n  scgi_temp_path        /tmp/scgi_temp;\n\n  client_max_body_size  4M;\n\n  proxy_read_timeout    600; ## 10 minutes\n  proxy_send_timeout    600;\n  proxy_connect_timeout 600;\n\n  proxy_http_version    1.1;\n\n  default_type application/octet-stream;\n  log_format   main '$remote_addr - $remote_user [$time_local]  $status '\n        '\"$request\" $body_bytes_sent \"$http_referer\" '\n        '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n  # Exclude specific requests from logging\n  map $request_uri $track {\n    default 1;\n    ~^/$ 0;\n    ~^/health 0;\n    ~^/metrics 0;\n  }\n\n  # simple_upstream preset\n  log_format access_log_exporter '$http_host\\t$request_method\\t$status\\t$request_completion\\t$request_time\\t$request_length\\t$bytes_sent\\t$upstream_addr\\t$upstream_connect_time\\t$upstream_header_time\\t$upstream_response_time\\t$request_uri';\n  access_log syslog:server=127.0.0.1:8514,nohostname access_log_exporter if=$track;\n  access_log   /dev/stderr  main;\n\n  sendfile     on;\n  tcp_nopush   on;\n  resolver kube-dns.kube-system.svc.cluster.local.;\n\n  # if the X-Query-Tags header is empty, set a noop= without a value as empty values are not logged\n  map $http_x_query_tags $query_tags {\n    \"\"        \"noop=\";            # When header is empty, set noop=\n    default   $http_x_query_tags; # Otherwise, preserve the original value\n  }\n\n  server {\n    listen             8080;\n    listen             [::]:8080;\n\n    location = / {\n      \n      return 200 'OK';\n      auth_basic off;\n    }\n\n    location = /stub_status {\n      stub_status on;\n      satisfy any;\n      access_log off;\n      allow 127.0.0.1;\n      deny all;\n      server_tokens on;  # expose nginx version\n    }\n\n    ########################################################\n    # Configure backend targets\n    location ^~ /ui {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n\n    # Distributor\n    location = /api/prom/push {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /loki/api/v1/push {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /distributor/ring {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /otlp/v1/logs {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n\n    # Ingester\n    location = /flush {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location ^~ /ingester/ {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /ingester {\n      \n      internal;        # to suppress 301\n    }\n\n    # Ring\n    location = /ring {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n\n    # MemberListKV\n    location = /memberlist {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n\n    # Ruler\n    location = /ruler/ring {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /api/prom/rules {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location ^~ /api/prom/rules/ {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /loki/api/v1/rules {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location ^~ /loki/api/v1/rules/ {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /prometheus/api/v1/alerts {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /prometheus/api/v1/rules {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n\n    # Compactor\n    location = /compactor/ring {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /loki/api/v1/delete {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /loki/api/v1/cache/generation_numbers {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n\n    # IndexGateway\n    location = /indexgateway/ring {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n\n    # QueryScheduler\n    location = /scheduler/ring {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n\n    # Config\n    location = /config {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n\n    # QueryFrontend, Querier\n    location = /api/prom/tail {\n      proxy_set_header Upgrade $http_upgrade;\n      proxy_set_header Connection \"upgrade\";\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /loki/api/v1/tail {\n      proxy_set_header Upgrade $http_upgrade;\n      proxy_set_header Connection \"upgrade\";\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location ^~ /api/prom/ {\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /api/prom {\n      \n      internal;        # to suppress 301\n    }\n    location ^~ /loki/api/v1/ {\n      # pass custom headers set by Grafana as X-Query-Tags which are logged as key/value pairs in metrics.go log messages\n      proxy_set_header X-Query-Tags \"${query_tags},user=${http_x_grafana_user},dashboard_id=${http_x_dashboard_uid},dashboard_title=${http_x_dashboard_title},panel_id=${http_x_panel_id},panel_title=${http_x_panel_title},source_rule_uid=${http_x_rule_uid},rule_name=${http_x_rule_name},rule_folder=${http_x_rule_folder},rule_version=${http_x_rule_version},rule_source=${http_x_rule_source},rule_type=${http_x_rule_type}\";\n      \n      set $backend     \"http://loki.loki.svc.cluster.local:3100\";\n      proxy_pass       $backend$request_uri;\n    }\n    location = /loki/api/v1 {\n      \n      internal;        # to suppress 301\n    }\n  }\n}\n"
  access-log-exporter.yaml: |
    presets:
      loki:
        metrics:
          - name: "http_requests_total"
            type: "counter"
            help: "The total number of client requests."
            labels:
              - name: "host"
                lineIndex: 0
              - name: "method"
                lineIndex: 1
              - name: "status"
                lineIndex: 2
              - name: "path"
                lineIndex: 11
                replacements:
                  - regexp: "^$"
                    replacement: "/"
                  - regexp: "^(.+)\\?.+"
                    replacement: "$1"

          - name: "http_requests_completed_total"
            type: "counter"
            help: "The total number of completed requests."
            valueIndex: 3
            replacements:
              - string: "OK"
                replacement: "1"
            labels:
              - name: "host"
                lineIndex: 0
              - name: "method"
                lineIndex: 1
              - name: "status"
                lineIndex: 2
              - name: "path"
                lineIndex: 11
                replacements:
                  - regexp: "^$"
                    replacement: "/"
                  - regexp: "^(.+)\\?.+"
                    replacement: "$1"

          - name: "http_request_size_bytes"
            type: "histogram"
            buckets: [ 10,1000,100000,1000000,5000000,50000000,200000000 ]
            help: "The request length (including request line, header, and request body)"
            valueIndex: 5
            labels:
              - name: "host"
                lineIndex: 0
              - name: "method"
                lineIndex: 1
              - name: "status"
                lineIndex: 2
              - name: "path"
                lineIndex: 11
                replacements:
                  - regexp: "^$"
                    replacement: "/"
                  - regexp: "^(.+)\\?.+"
                    replacement: "$1"

          - name: "http_response_size_bytes"
            type: "histogram"
            buckets: [ 10,1000,100000,1000000,5000000,50000000,200000000 ]
            help: "The response length (including request line, header, and request body)"
            valueIndex: 6
            labels:
              - name: "host"
                lineIndex: 0
              - name: "method"
                lineIndex: 1
              - name: "status"
                lineIndex: 2
              - name: "path"
                lineIndex: 11
                replacements:
                  - regexp: "^$"
                    replacement: "/"
                  - regexp: "^(.+)\\?.+"
                    replacement: "$1"

          - name: "http_request_duration_seconds"
            type: "histogram"
            buckets: [ .005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10 ]
            help: "The time spent on receiving and response the response to the client"
            valueIndex: 4
            math:
              enabled: true
              div: 1000
            labels:
              - name: "host"
                lineIndex: 0
              - name: "method"
                lineIndex: 1
              - name: "status"
                lineIndex: 2
              - name: "path"
                lineIndex: 11
                replacements:
                  - regexp: "^$"
                    replacement: "/"
                  - regexp: "^(.+)\\?.+"
                    replacement: "$1"

          - name: "http_upstream_connect_duration_seconds"
            type: "histogram"
            buckets: [ .005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10 ]
            help: "The time spent on establishing a connection with the upstream server"
            valueIndex: 8
            math:
              enabled: true
              div: 1000
            upstream:
              enabled: true
              addrLineIndex: 7
              excludes: []
            labels:
              - name: "host"
                lineIndex: 0
              - name: "method"
                lineIndex: 1
              - name: "status"
                lineIndex: 2
              - name: "path"
                lineIndex: 11
                replacements:
                  - regexp: "^$"
                    replacement: "/"
                  - regexp: "^(.+)\\?.+"
                    replacement: "$1"

          - name: "http_upstream_header_duration_seconds"
            type: "histogram"
            help: "The time spent on receiving the response header from the upstream server"
            buckets: [ .005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10 ]
            valueIndex: 9
            math:
              enabled: true
              div: 1000
            upstream:
              enabled: true
              addrLineIndex: 7
              excludes: []
            labels:
              - name: "host"
                lineIndex: 0
              - name: "method"
                lineIndex: 1
              - name: "status"
                lineIndex: 2
              - name: "path"
                lineIndex: 11
                replacements:
                  - regexp: "^$"
                    replacement: "/"
                  - regexp: "^(.+)\\?.+"
                    replacement: "$1"

          - name: "http_upstream_request_duration_seconds"
            type: "histogram"
            help: "The time spent on receiving the response from the upstream server"
            buckets: [ .005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10 ]
            valueIndex: 10
            math:
              enabled: true
              div: 1000
            upstream:
              enabled: true
              addrLineIndex: 7
              excludes: []
            labels:
              - name: "host"
                lineIndex: 0
              - name: "method"
                lineIndex: 1
              - name: "status"
                lineIndex: 2
              - name: "path"
                lineIndex: 11
                replacements:
                  - regexp: "^$"
                    replacement: "/"
                  - regexp: "^(.+)\\?.+"
                    replacement: "$1"
