Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
software:fluent-bit-loki-grafana:fluent-bit:docker-swarm-2 [2025/11/26 01:17] – [parsers_multiline.conf] mirocowsoftware:fluent-bit-loki-grafana:fluent-bit:docker-swarm-2 [2025/12/06 03:35] (текущий) mirocow
Строка 1: Строка 1:
-====== Обработка многострочных логов ======+====== Обработка логов Docker ======
  
 === fluent-bit.conf === === fluent-bit.conf ===
Строка 23: Строка 23:
     Parser            docker     Parser            docker
     Refresh_Interval  10     Refresh_Interval  10
 +    Ignore_Older      1h
     Docker_Mode       On     Docker_Mode       On
-    Docker_Mode_Flush 4 
     Tag               docker.<file_name>     Tag               docker.<file_name>
-    Tag_Regex         (?<file_name>[a-z0-9]*)-json.log+    Tag_Regex         (?<file_name>[a-f0-9]*)-json.log
     Mem_Buf_Limit     50MB     Mem_Buf_Limit     50MB
     Skip_Long_Lines   On     Skip_Long_Lines   On
Строка 32: Строка 32:
     DB.sync           normal     DB.sync           normal
     Storage.Type      filesystem     Storage.Type      filesystem
-    Read_from_Head    true+    Read_from_Head    false
  
-Обработка многострочных логов ДО парсеров +Только для отладки 
-[FILTER+[INPUT
-    Name                multiline +#     Name              tail 
-    Match               docker.* +#     Path              /var/lib/docker/containers/*/*.log 
-    multiline.key_content log +#     Parser            docker 
-    multiline.parser    java_multiline, python_multiline, ruby_multiline, sidekiq_multiline, gitlab_rails_multiline, stacktrace_multiline+#     Refresh_Interval  10 
 +#     Docker_Mode       On 
 +#     Tag               docker.<file_name> 
 +#     Tag_Regex         (?<file_name>[a-f0-9]*)-json.log 
 +#     Mem_Buf_Limit     50MB 
 +#     Skip_Long_Lines   On 
 +#     DB                /var/log/flb-storage/flb_db.db 
 +#     DB.sync           normal 
 +#     Storage.Type      filesystem 
 +#     Read_from_Head    true
  
-Метаданные Docker+Фильтруем пустые логи
 [FILTER] [FILTER]
-    name                lua+    name                grep
     match               docker.*     match               docker.*
-    script              /fluent-bit/bin/docker-metadata.lua +    Exclude             log ^$ 
-    call                enrich_with_docker_metadata+    Exclude             log ^\s*$ 
 +    Exclude             log ^==>.+<==$
  
 # Извлекаем сырой лог # Извлекаем сырой лог
Строка 53: Строка 63:
     match               docker.*     match               docker.*
     copy                log raw_log     copy                log raw_log
 +    copy                exception.backtrace exception_backtrace
 +    copy                exception.class exception_class
 +    copy                exception.message exception_message
  
-Фильтруем пустые логи+Очищаем docker.* - оставляем ТОЛЬКО нужные поля
 [FILTER] [FILTER]
-    name                grep+    name                record_modifier
     match               docker.*     match               docker.*
-    Exclude             raw_log ^$ 
-    Exclude             raw_log ^\s*$ 
-    Exclude             raw_log ^==>.+<==$ 
-    Exclude             raw_log ^{"message":"\s*"}$ 
  
-# Основной JSON парсинг для Docker логов +    whitelist_key       date 
-[FILTER] +    whitelist_key       log 
-    Name                parser +    whitelist_key       raw_log 
-    Match               docker.* +    whitelist_key       exception_backtrace 
-    Key_Name            log +    whitelist_key       exception_class 
-    Parser              json_auto +    whitelist_key       exception_message
-    Reserve_Data        On +
-    Preserve_Key        On+
  
-# Цепочка специализированных парсеров для raw_log +    whitelist_key       method 
-[FILTER] +    whitelist_key       path 
-    name                parser +    whitelist_key       action 
-    match               docker.* +    whitelist_key       status 
-    key_name            raw_log +    whitelist_key       remote_ip 
-    parser              gitlab_json +    whitelist_key       controller 
-    reserve_data        true+    whitelist_key       line_id
  
-[FILTER] +# 
-    name                parser +# FILTERS 
-    match               docker.* +#
-    key_name            raw_log +
-    parser              sidekiq_json +
-    reserve_data        true+
  
 [FILTER] [FILTER]
Строка 98: Строка 102:
     match               docker.*     match               docker.*
     key_name            raw_log     key_name            raw_log
-    parser              gitlab_registry+    parser              gitlab_json
     reserve_data        true     reserve_data        true
  
Строка 105: Строка 109:
     match               docker.*     match               docker.*
     key_name            raw_log     key_name            raw_log
-    parser              nextcloud_access+    parser              gitlab_registry
     reserve_data        true     reserve_data        true
-    Preserve_Key        true 
  
 [FILTER] [FILTER]
Строка 113: Строка 116:
     match               docker.*     match               docker.*
     key_name            raw_log     key_name            raw_log
-    parser              apache_access+    parser              sidekiq_json
     reserve_data        true     reserve_data        true
  
Строка 148: Строка 151:
     match               docker.*     match               docker.*
     key_name            raw_log     key_name            raw_log
-    parser              php_fpm+    parser              nextcloud_access
     reserve_data        true     reserve_data        true
 +    Preserve_Key        true
  
 [FILTER] [FILTER]
Строка 155: Строка 159:
     match               docker.*     match               docker.*
     key_name            raw_log     key_name            raw_log
-    parser              grafana_regex+    parser              apache_access
     reserve_data        true     reserve_data        true
  
Строка 162: Строка 166:
     match               docker.*     match               docker.*
     key_name            raw_log     key_name            raw_log
-    parser              grafana_logfmt+    parser              php_fpm
     reserve_data        true     reserve_data        true
  
Строка 169: Строка 173:
     match               docker.*     match               docker.*
     key_name            raw_log     key_name            raw_log
-    parser              syslog_rfc3164 +    parser              grafana_regex
-    reserve_data        true +
- +
-# Дополнительные парсеры для разных языков +
-[FILTER] +
-    name                parser +
-    match               docker.* +
-    key_name            raw_log +
-    parser              ruby_multiline +
-    reserve_data        true +
- +
-[FILTER] +
-    name                parser +
-    match               docker.* +
-    key_name            raw_log +
-    parser              java_multiline +
-    reserve_data        true +
- +
-[FILTER] +
-    name                parser +
-    match               docker.* +
-    key_name            raw_log +
-    parser              python_multiline+
     reserve_data        true     reserve_data        true
  
-# Структуризация распарсенных полей из raw_log+# Структуризация распарсенных полей В raw_log
 [FILTER] [FILTER]
     name                nest     name                nest
Строка 216: Строка 198:
     wildcard            statusCode     wildcard            statusCode
     wildcard            resourcePath     wildcard            resourcePath
-    wildcard            correlation_id +    wildcard            exception
-    wildcard            component +
-    wildcard            severity +
-    wildcard            grpc.* +
-    wildcard            pid +
-    wildcard            tid +
-    wildcard            thread +
-    wildcard            class +
-    wildcard            name +
-    wildcard            query_time +
-    wildcard            lock_time +
-    wildcard            rows_sent +
-    wildcard            rows_examined +
-    wildcard            query +
-    wildcard            duration +
-    wildcard            pri +
-    wildcard            ident +
-    wildcard            error+
     nest_under          parsed_data     nest_under          parsed_data
  
-# Копируем метаданные Docker+
 +# FILTERS 
 +
 + 
 +# Метаданные Docker 
 +[FILTER] 
 +    name                lua 
 +    match               docker.* 
 +    script              /fluent-bit/bin/docker-metadata.lua 
 +    call                enrich_with_docker_metadata 
 + 
 +# Копируем метаданные
 [FILTER] [FILTER]
     name                modify     name                modify
Строка 243: Строка 219:
     copy                docker.container_started started     copy                docker.container_started started
     copy                docker.container_name container_name     copy                docker.container_name container_name
 +    copy                docker.container_name service_name
     copy                docker.container_id container_id     copy                docker.container_id container_id
     copy                docker.state state     copy                docker.state state
     copy                docker.stream stream     copy                docker.stream stream
 +    copy                docker.line_id line_id
 +
     copy                log _raw     copy                log _raw
     copy                parsed_data _parsed     copy                parsed_data _parsed
 +    # copy                exception_class _class
 +    # copy                exception_message _message
 +    # copy                exception_backtrace _backtrace
  
-    # docker compose +    copy                docker.label_project project 
-    copy                docker.label_compose_project compose_project +    copy                docker.label_service service 
-    copy                docker.label_compose_service compose_service +    copy                docker.label_logging logging 
- +    copy                docker.label_logging_jobname logging_jobname
-    # docker swarm +
-    copy                docker.Label_stack_name stack_name +
-    copy                docker.Label_service_name service_name +
-    copy                docker.Label_service_id service_id +
-    copy                docker.Label_task_name task_name +
-    copy                docker.Label_task_id task_id +
-    copy                docker.Label_node_id node_id +
- +
-    # Labels +
-    copy                docker.Label_logging logging +
-    copy                docker.Label_logging_jobname logging_jobname+
  
 # Структурируем через nest # Структурируем через nest
Строка 281: Строка 252:
     set                 node_name ${NODE_NAME}     set                 node_name ${NODE_NAME}
     set                 host_name ${NODE_NAME}     set                 host_name ${NODE_NAME}
-    set                 log_source docker_swarm 
-    set                 environment production 
  
 # Перетагиваем только логи с enabled logging # Перетагиваем только логи с enabled logging
Строка 288: Строка 257:
     name                rewrite_tag     name                rewrite_tag
     match               docker.*     match               docker.*
-    rule                $logging ^enabled$ data.$container_name.$TAG true+    rule                $logging ^enabled$ data.$container_id true
  
-# Очищаем data.* - расширенный whitelist 
 [FILTER] [FILTER]
     name                record_modifier     name                record_modifier
     match               data.*     match               data.*
 +
 +    whitelist_key       date
     whitelist_key       log     whitelist_key       log
 +    whitelist_key       exception_class
 +    whitelist_key       exception_message
 +    whitelist_key       exception_backtrace
 +
 +    whitelist_key       method
 +    whitelist_key       path
 +    whitelist_key       action
 +    whitelist_key       status
 +    whitelist_key       remote_ip
 +    whitelist_key       controller
 +    whitelist_key       line_id
 +
 +    whitelist_key       node_id
 +    whitelist_key       node_name
 +    whitelist_key       host_name
 +    whitelist_key       hostname
     whitelist_key       started     whitelist_key       started
-    whitelist_key       hostname +    whitelist_key       container_name 
-    whitelist_key       state+    whitelist_key       service_name
     whitelist_key       container_id     whitelist_key       container_id
-    whitelist_key       container_name +    whitelist_key       stream 
-    whitelist_key       logging+    whitelist_key       project 
 +    whitelist_key       service
     whitelist_key       logging_jobname     whitelist_key       logging_jobname
-    whitelist_key       stream 
-    whitelist_key       node_name 
-    whitelist_key       host_name 
-    whitelist_key       log_source 
-    whitelist_key       environment 
- 
-    # docker compose 
-    whitelist_key       compose_project 
-    whitelist_key       compose_service 
- 
-    # docker swarm 
-    whitelist_key       stack_name 
-    whitelist_key       service_name 
-    whitelist_key       service_id 
-    whitelist_key       task_name 
-    whitelist_key       task_id 
-    whitelist_key       node_id 
- 
-    # parsed data 
-    whitelist_key       parsed_data 
  
 [OUTPUT] [OUTPUT]
Строка 328: Строка 295:
     host                loki     host                loki
     port                3100     port                3100
-    labels              job=$logging_jobname, node_name=$node_name, container_name=$container_name, service_name=$service_name, stack_name=$stack_nameenvironment=$environment +    labels              job=$logging_jobname, node_name=$node_name, container_id=$container_id, container_name=$container_name, service_name=$service_name, project=$projectservice=$service, level=$stream 
-    label_keys          container_name,service_name,stack_name,node_name,environment+    label_keys          $node_name,$container_id,$container_name,$service_name,$project,$service
     line_format         json     line_format         json
     auto_kubernetes_labels off     auto_kubernetes_labels off
-    drop_single_key     false 
-    remove_keys         docker_id 
  
 +# Только для отладки
 # [OUTPUT] # [OUTPUT]
 #     name                stdout #     name                stdout
Строка 341: Строка 307:
 </code> </code>
  
-=== parsers_multiline.conf ===+=== parsers.conf ===
  
 <code ini> <code ini>
Строка 347: Строка 313:
 [PARSER] [PARSER]
     Name        docker     Name        docker
-    Format      json 
-    Time_Key    time 
-    Time_Format %Y-%m-%dT%H:%M:%S.%LZ 
-    Time_Keep   On 
- 
-# Автоматический JSON парсер 
-[PARSER] 
-    Name        json_auto 
     Format      json     Format      json
     Time_Key    time     Time_Key    time
Строка 367: Строка 325:
     Time_Key    timestamp     Time_Key    timestamp
     Time_Format %d/%b/%Y:%H:%M:%S %z     Time_Format %d/%b/%Y:%H:%M:%S %z
-    Time_Keep   On 
  
 # Gitlab JSON логи (application logs) # Gitlab JSON логи (application logs)
Строка 373: Строка 330:
     Name        gitlab_json     Name        gitlab_json
     Format      json     Format      json
 +    # Time_Key    time    # Используем время из Docker
     Time_Keep   On     Time_Keep   On
  
Строка 388: Строка 346:
     Name        sidekiq_json     Name        sidekiq_json
     Format      json     Format      json
 +    # Time_Key    time    # Используем время из Docker
     Time_Keep   On     Time_Keep   On
  
Строка 396: Строка 355:
     Regex       ^(?<remote_ip>[^ ]*) (?<user_ident>[^ ]*) (?<user_id>[^ ]*) \[(?<timestamp>[^\]]*)\] "(?<method>\w+) (?<path>[^ ]*) HTTP/[0-9.]+" (?<status>\d+) (?<body_bytes>\d+) "(?<referrer>[^"]*)" "(?<user_agent>[^"]*)"     Regex       ^(?<remote_ip>[^ ]*) (?<user_ident>[^ ]*) (?<user_id>[^ ]*) \[(?<timestamp>[^\]]*)\] "(?<method>\w+) (?<path>[^ ]*) HTTP/[0-9.]+" (?<status>\d+) (?<body_bytes>\d+) "(?<referrer>[^"]*)" "(?<user_agent>[^"]*)"
     Time_Key    timestamp     Time_Key    timestamp
-    Time_Format %d/%b/%Y:%H:%M:%S %z+    Time_Format %d/%b/%Y:%H:%M:%S %z  # ← Apache/Nginx формат!
     Time_Keep   On     Time_Keep   On
  
Строка 406: Строка 365:
     Time_Key    timestamp     Time_Key    timestamp
     Time_Format %d/%b/%Y:%H:%M:%S %z     Time_Format %d/%b/%Y:%H:%M:%S %z
-    Time_Keep   On 
  
 # MySQL error логи # MySQL error логи
Строка 475: Строка 433:
     Regex       logger=(?<logger>[^ ]*) endpoint=(?<endpoint>[^ ]*) pluginId=(?<pluginId>[^ ]*) dsName=(?<dsName>[^ ]*) dsUID=(?<dsUID>[^ ]*) uname=(?<uname>[^ ]*) t=(?<t>[^ ]*) level=(?<level>[^ ]*) msg="(?<msg>[^"]*)" error=(?<error>[^ ]*) statusCode=(?<statusCode>[^ ]*) resourcePath="(?<resourcePath>[^"]*)"     Regex       logger=(?<logger>[^ ]*) endpoint=(?<endpoint>[^ ]*) pluginId=(?<pluginId>[^ ]*) dsName=(?<dsName>[^ ]*) dsUID=(?<dsUID>[^ ]*) uname=(?<uname>[^ ]*) t=(?<t>[^ ]*) level=(?<level>[^ ]*) msg="(?<msg>[^"]*)" error=(?<error>[^ ]*) statusCode=(?<statusCode>[^ ]*) resourcePath="(?<resourcePath>[^"]*)"
     Time_Key    t     Time_Key    t
-    Time_Format %Y-%m-%dT%H:%M:%S.%LZ 
-    Time_Keep   On 
- 
-# Ruby/Rails логи (GitLab) 
-[PARSER] 
-    Name        ruby_multiline 
-    Format      regex 
-    Regex       ^(?<time>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z) \[(?<pid>\d+)\] (?<level>\w+) -- : (?<message>.*) 
-    Time_Key    time 
-    Time_Format %Y-%m-%dT%H:%M:%S.%LZ 
-    Time_Keep   On 
- 
-# GitLab Rails логи (JSON multiline) 
-[PARSER] 
-    Name        gitlab_rails_multiline 
-    Format      regex 
-    Regex       ^(?<time>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z) .*?"@timestamp":"(?<json_time>[^"]*)".*?"level":"(?<level>[^"]*)".*?"message":"(?<message>[^"]*)" 
-    Time_Key    time 
-    Time_Format %Y-%m-%dT%H:%M:%S.%LZ 
-    Time_Keep   On 
- 
-# Sidekiq multiline логи 
-[PARSER] 
-    Name        sidekiq_multiline 
-    Format      regex 
-    Regex       ^(?<time>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z) (?<pid>\d+) TID-(?<tid>\w+) (?<level>\w+): (?<message>.*) 
-    Time_Key    time 
-    Time_Format %Y-%m-%dT%H:%M:%S.%LZ 
-    Time_Keep   On 
- 
-# Multiline Java/Spring логи 
-[PARSER] 
-    Name        java_multiline 
-    Format      regex 
-    Regex       ^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+) (?<level>\w+)\s+--- \[(?<thread>[^\]]+)\] (?<class>\S+)\s*:(?<message>.*) 
-    Time_Key    time 
-    Time_Format %Y-%m-%d %H:%M:%S.%L 
-    Time_Keep   On 
- 
-# Multiline Python логи 
-[PARSER] 
-    Name        python_multiline 
-    Format      regex 
-    Regex       ^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d+) - (?<name>\w+) - (?<level>\w+) - (?<message>.*) 
-    Time_Key    time 
-    Time_Format %Y-%m-%d %H:%M:%S,%L 
-    Time_Keep   On 
- 
-# Multiline стектрейсы 
-[PARSER] 
-    Name        stacktrace_multiline 
-    Format      regex 
-    Regex       ^(?<timestamp>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+)\s+(?<level>\w+)\s+(?<message>.*) 
-    Time_Key    timestamp 
-    Time_Format %Y-%m-%d %H:%M:%S.%L 
-    Time_Keep   On 
- 
-# Дополнительный парсер для Go логов 
-[PARSER] 
-    Name        go_multiline 
-    Format      regex 
-    Regex       ^(?<time>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z)\s+(?<level>\w+)\s+(?<message>.*) 
-    Time_Key    time 
     Time_Format %Y-%m-%dT%H:%M:%S.%LZ     Time_Format %Y-%m-%dT%H:%M:%S.%LZ
     Time_Keep   On     Time_Keep   On
Строка 551: Строка 446:
  
 <code yaml> <code yaml>
 +auth_enabled: false
 +
 +server:
 +  http_listen_port: 3100
 +
 +common:
 +  instance_addr: 127.0.0.1
 +  path_prefix: /loki
 +  storage:
 +    filesystem:
 +      chunks_directory: /loki/chunks
 +      rules_directory: /loki/rules
 +  replication_factor: 1
 +  ring:
 +    kvstore:
 +      store: inmemory
  
 +schema_config:
 +  configs:
 +    - from: 2020-10-24
 +      store: tsdb
 +      object_store: filesystem
 +      schema: v13
 +      index:
 +        prefix: index_
 +        period: 24h
 +
 +ruler:
 +  alertmanager_url: http://localhost:9093
 +
 +limits_config:
 +  retention_period: 720h
 +  reject_old_samples: true
 +  reject_old_samples_max_age: 720h
 +  allow_structured_metadata: true
 +  max_query_length: 721h
 +  
 +ingester:
 +  lifecycler:
 +    ring:
 +      kvstore:
 +        store: inmemory
 +      replication_factor: 1
 +    final_sleep: 0s
 +  chunk_idle_period: 1h
 +  max_chunk_age: 1h
 +  chunk_target_size: 1048576
 +  chunk_retain_period: 30s
 +
 +table_manager:
 +  retention_deletes_enabled: true
 +  retention_period: 720h
 </code> </code>
  
Строка 563: Строка 509:
  
 <code bash> <code bash>
 +# Проверяем конфигурацию
 +$ docker exec -it <fluentbit_container> /fluent-bit/bin/fluent-bit -c /fluent-bit/etc/fluent-bit.conf --dry-run
  
 +# Смотрим логи
 +$ docker service logs logging_fluent-bit
 +
 +# Проверяем метрики
 +$ curl http://localhost:2020/api/v1/metrics | jq
 +
 +# Тестируем парсеры
 +$ echo '2025-11-21T02:13:34.366Z {"method":"PUT","path":"/projects","status":500}' | \
 +$ docker exec -i <fluentbit_container> /fluent-bit/bin/fluent-bit -c /fluent-bit/etc/fluent-bit.conf -i stdin -o stdout
 </code> </code>
  
 ==== Запросы в Grafana ==== ==== Запросы в Grafana ====
  
-<code>+<code json>
 {job="fluent-bit"} |= "gitlab" {job="fluent-bit"} |= "gitlab"
-</code> 
  
-<code> 
 {container_name="gitlab" {container_name="gitlab"
-</code> 
  
-<code> 
 {job="fluent-bit"} |~ "(?i)error|exception|fail" {job="fluent-bit"} |~ "(?i)error|exception|fail"
-</code> 
  
-<code> 
 {node_name="node-1"} {node_name="node-1"}
-</code> 
  
-<code> 
 # Все логи GitLab # Все логи GitLab
 {container_name=~".*gitlab.*" {container_name=~".*gitlab.*"
-</code> 
  
-<code> 
 # Логи по компонентам # Логи по компонентам
 {container_name=~".*gitlab.*"} | json | component="gitaly.UnaryServerInterceptor" {container_name=~".*gitlab.*"} | json | component="gitaly.UnaryServerInterceptor"
-</code> 
  
-<code> 
 # Ошибки # Ошибки
 {container_name=~".*gitlab.*"} | json | level="error" {container_name=~".*gitlab.*"} | json | level="error"
-</code> 
  
-<code> 
 # Запросы с определенным correlation_id # Запросы с определенным correlation_id
 {container_name=~".*gitlab.*"} | json | correlation_id="01KAJ30DCE4BW6JSAT7KHGZ9PX" {container_name=~".*gitlab.*"} | json | correlation_id="01KAJ30DCE4BW6JSAT7KHGZ9PX"
-</code> 
  
-<code> 
 # Логи Sidekiq # Логи Sidekiq
 {container_name=~".*gitlab.*"} | json | severity="INFO" {container_name=~".*gitlab.*"} | json | severity="INFO"
 +
 +# Все логи GitLab с parsed_data
 +{container_name=~".*gitlab.*"} | json
 +
 +# Логи с ошибками
 +{environment="production"} | json | level="error" 
 +
 +# Медленные PostgreSQL запросы
 +{service_name=~".*postgres.*"} | json | duration > 1000
 +
 +# Nginx 5xx ошибки
 +{container_name=~".*nginx.*"} | json | status >= 500
 +
 +# Sidekiq логи
 +{container_name=~".*sidekiq.*"} | json | severity="INFO"
 </code> </code>