Describe the bug
I am encountering an issue where logs ingested using Fluent Bit are not being tailed correctly in Loki 3.x versions. Logs seem to be dropped or are missing when tailing logs using the gRPC client or log-cli. This issue does not occur in Loki 2.9.10, where all logs are tailed correctly without any missing entries. (even with the --delay-for arg set)
To Reproduce
Steps to reproduce the behavior:
Started Loki with versions 3.x (where the issue is present).
Fluent Bit (v3.1.1) is reading Docker logs and sending them to Loki.
Tail logs using one of the following methods:
• gRPC client (custom implementation).
• Loki CLI with the following query:
Expected behavior
All logs ingested into Loki should appear in the tail stream in order and without any dropped or missing entries, even during high log throughput.
Environment:
• Loki Version: 3.x (issue present); 2.9.10 (working as expected)
• Fluent Bit Version: v3.1.1
• Infrastructure: Docker
• Deployment tool: Docker containers (both Fluent Bit and Loki deployed as containers)
• Log Source: Docker logs from a custom mock-service Python application
• Fluent Bit Configuration (fluent-bit-config.yaml):
CJSON = require("cjson")
CACHE = {}
local function get_container_name(container_id)
local metadata = CACHE[container_id]
if metadata then
return metadata.docker_container_name
end
-- Read config file
local config_file_path = "/var/lib/docker/containers/" .. container_id .. "/config.v2.json"
local config_file = io.open(config_file_path, "rb")
if not config_file then
return nil
end
local config_json = config_file:read("*a")
config_file:close()
-- Map json config
local config = CJSON.decode(config_json)
-- Get container name and cache it
local container_name = config.Name:gsub("^/", "")
CACHE[container_id] = { docker_container_name = container_name }
return container_name
end
function Enrich(tag, timestamp, record)
-- Get container id from tag
local container_id = tag:match("docker_tail%.(.+)")
if not container_id then
return 0, timestamp, record
end
-- Get container name and enrich record
local container_name = get_container_name(container_id)
if container_name then
record["_metadata_docker_container_name"] = container_name
end
return 1, timestamp, record
end
• Loki Configuration in (config/loki-config.yaml):
from typing import Any
import datetime
import uuid
from fastapi import FastAPI
import structlog
import uvicorn
APP_NAME = "mock-service"
logger: Any = structlog.get_logger()
app: FastAPI = FastAPI(title="Mock Service", description="Mock Service", version="0.1.0")
class CustomPrintLogger:
def msg(self, message: Any) -> None:
print(message)
logger = structlog.wrap_logger(
CustomPrintLogger(),
wrapper_class=structlog.BoundLogger,
processors=[structlog.processors.JSONRenderer()],
)
@app.get("/levels")
def levels() -> dict[str, Any]:
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="fatal", appName=APP_NAME, message="mock message", host="mock-host",
compName="mock-component")
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="critical", appName=APP_NAME, message="mock message", host="mock-host",
compName="mock-component")
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="error", appName=APP_NAME, message="mock message", host="mock-host",
compName="mock-component")
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="warn", appName=APP_NAME, message="mock message", host="mock-host",
compName="mock-component")
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="warning", appName=APP_NAME, message="mock message", host="mock-host",
compName="mock-component")
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="info", appName=APP_NAME, message="mock message", host="mock-host",
compName="mock-component")
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="debug", appName=APP_NAME, message="mock message", host="mock-host",
compName="mock-component")
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="trace", appName=APP_NAME, message="mock message", host="mock-host",
compName="mock-component")
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="unknown", appName=APP_NAME, message="mock message", host="mock-host",
compName="mock-component")
logger.msg("mock-event", time=str(datetime.datetime.now(datetime.timezone.utc)),
level="random", appName=APP_NAME, message=f"mock message {uuid.uuid4()}",
host="mock-host", compName="mock-component")
print("FATAL: This is an example of unstructured log line")
print("CRITICAL: This is an example of unstructured log line")
print("ERROR: This is an example of unstructured log line")
print("WARN: This is an example of unstructured log line")
print("WARNING: This is an example of unstructured log line")
print("INFO: This is an example of unstructured log line")
print("DEBUG: This is an example of unstructured log line")
print("TRACE: This is an example of unstructured log line")
print("UNKNOWN: This is an example of unstructured log line")
print(f"RANDOM: This is an example of unstructured log line {uuid.uuid4()}")
return {}
if __name__ == "__main__":
structlog.configure(
processors=[
structlog.stdlib.filter_by_level,
structlog.processors.TimeStamper(fmt="iso", key="time"),
structlog.processors.JSONRenderer(),
],
context_class=dict,
logger_factory=structlog.stdlib.LoggerFactory(),
)
uvicorn.run("main:app", host="0.0.0.0", port=9012, reload=True, log_level="critical")
docker run --name mock-service -p 9012:9012 mock-custom:latest
docker build -t mock-custom:latest -f fake.dockerfile .
curl 127.0.0.1:9012/levels # to generate logs
Screenshots, Promtail config, or terminal output
Current result
Describe the bug I am encountering an issue where logs ingested using Fluent Bit are not being tailed correctly in Loki 3.x versions. Logs seem to be dropped or are missing when tailing logs using the gRPC client or log-cli. This issue does not occur in Loki 2.9.10, where all logs are tailed correctly without any missing entries. (even with the --delay-for arg set)
To Reproduce Steps to reproduce the behavior:
Expected behavior All logs ingested into Loki should appear in the tail stream in order and without any dropped or missing entries, even during high log throughput.
Environment: • Loki Version: 3.x (issue present); 2.9.10 (working as expected) • Fluent Bit Version: v3.1.1 • Infrastructure: Docker • Deployment tool: Docker containers (both Fluent Bit and Loki deployed as containers) • Log Source: Docker logs from a custom mock-service Python application • Fluent Bit Configuration (fluent-bit-config.yaml):
• Fluent Bit Dockerfile:
• Fluent Bit (parsers.ini):
• Fluent Bit (docker_filter.lua):
• Loki Configuration in (config/loki-config.yaml):
Mock Service Dockerfile (fake.dockerfile):
Mock Service Code (main.py):
Screenshots, Promtail config, or terminal output Current result
Expected result