LogTide

No-SDK Setup

Use LogTide without installing any SDK. Just print to stdout - works with any language (Go, Rust, Python, Java, .NET, Ruby, PHP).

No SDK Required

LogTide supports stdout-based logging via Fluent Bit (self-hosted) or Docker logging drivers (cloud). Simply write to stdout/stderr and your logs will be automatically ingested.

Choose Your Method

Cloud (api.logtide.dev)

Use Docker's Fluentd logging driver to send logs directly to LogTide Cloud.

  • No Fluent Bit container needed
  • Configure once in docker-compose.yml
  • Zero code changes required
Self-Hosted

Add Fluent Bit to your LogTide installation to collect logs from all Docker containers automatically.

  • Optional Fluent Bit configuration
  • Automatic metadata enrichment
  • Full control over log processing

How It Works

LogTide uses Fluent Bit to automatically collect logs from Docker containers:

1
Your app writes to stdout/stderr
Use standard console.log, print(), fmt.Println() - whatever your language provides.
2
Docker captures container output
Docker's logging driver stores logs in JSON format at /var/lib/docker/containers/*/.
3
Fluent Bit collects and enriches
Fluent Bit tails container logs, adds metadata (container name, service), and formats for LogTide.
4
Logs sent to LogTide API
Fluent Bit sends logs to /api/v1/ingest/single with your API key automatically.

Setup Instructions (Cloud)

For LogTide Cloud, configure your Docker containers to use the Fluentd logging driver:

1. Configure docker-compose.yml

Add logging configuration to each service in your docker-compose.yml:

services:
my-app:
  image: my-app:latest
  logging:
    driver: fluentd
    options:
      fluentd-address: api.logtide.dev:24224
      fluentd-async: "true"
      tag: "lp_your_api_key_here.{{.Name}}"
      labels: "service"
  labels:
    service: "my-app"

Coming Soon

LogTide Cloud is currently in beta. Sign up at logtide.dev to get early access and we'll notify you when Fluentd logging driver support is available.

Setup Instructions (Self-Hosted)

1. Generate API Key

Create an API key in your LogTide project settings.

2. Configure Fluent Bit API Key

Add your API key to the docker/.env file:

# In docker/.env
FLUENT_BIT_API_KEY=lp_your_api_key_here

3. Restart Fluent Bit

docker compose restart fluent-bit

Setup Complete

All Docker containers now automatically send logs to LogTide. No code changes needed!

Language Examples

Just write to stdout/stderr using your language's standard logging. No special library needed.

Go

package main

import (
  "log"
  "encoding/json"
  "os"
)

func main() {
  // Simple text logging
  log.Println("Server started on port 8080")

  // Structured logging (JSON format recommended)
  logData := map[string]interface{}{
      "level":   "info",
      "message": "User logged in",
      "user_id": 12345,
      "ip":      "192.168.1.1",
  }
  json.NewEncoder(os.Stdout).Encode(logData)
}

Rust

use log::{info, error};
use env_logger;

fn main() {
  env_logger::init();

  info!("Application started");
  error!("Database connection failed");

  // Or use serde_json for structured logs
  println!("{}", serde_json::json!({
      "level": "info",
      "message": "Request processed",
      "duration_ms": 150
  }));
}

Python

import logging
import json

# Standard logging
logging.basicConfig(level=logging.INFO)
logging.info("Application started")

# Structured JSON logging
log_data = {
  "level": "info",
  "message": "User action",
  "user_id": 12345,
  "action": "login"
}
print(json.dumps(log_data))

Java

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.HashMap;

public class App {
  private static final Logger logger = LoggerFactory.getLogger(App.class);

  public static void main(String[] args) throws Exception {
      // Simple logging
      logger.info("Application started");

      // Structured logging (use Logback with JSON encoder)
      Map<String, Object> logData = new HashMap<>();
      logData.put("level", "info");
      logData.put("message", "Request received");
      logData.put("request_id", "abc123");

      System.out.println(new ObjectMapper().writeValueAsString(logData));
  }
}

.NET (C#)

using Serilog;
using Serilog.Formatting.Json;
using System;
using System.Text.Json;

class Program
{
  static void Main()
  {
      // Using Serilog with console sink
      Log.Logger = new LoggerConfiguration()
          .WriteTo.Console(new JsonFormatter())
          .CreateLogger();

      Log.Information("Application started");
      Log.Error("Database connection failed", new { UserId = 123 });

      // Or manual JSON
      var logData = new {
          level = "info",
          message = "User login",
          user_id = 12345
      };
      Console.WriteLine(JsonSerializer.Serialize(logData));
  }
}

Ruby

require 'logger'
require 'json'

# Standard logging
logger = Logger.new(STDOUT)
logger.info("Application started")

# Structured JSON logging
log_data = {
level: 'info',
message: 'User action',
user_id: 12345,
action: 'login'
}
puts log_data.to_json

PHP

<?php
// Simple logging
error_log("Application started");

// Structured JSON logging
$logData = [
  'level' => 'info',
  'message' => 'User login',
  'user_id' => 12345,
  'ip' => $_SERVER['REMOTE_ADDR']
];
echo json_encode($logData) . "
";
?>

Docker Configuration

Add Fluent Bit to your docker-compose.yml to enable automatic log collection from Docker containers:

# Add this service to your docker-compose.yml
fluent-bit:
image: fluent/fluent-bit:4.2.2  # For ARM64/Raspberry Pi: cr.fluentbit.io/fluent/fluent-bit:4.2.2
container_name: logtide-fluent-bit
volumes:
  - ./fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf:ro
  - ./parsers.conf:/fluent-bit/etc/parsers.conf:ro
  - /var/lib/docker/containers:/var/lib/docker/containers:ro
  - /var/run/docker.sock:/var/run/docker.sock:ro
environment:
  LOGTIDE_API_KEY: ${FLUENT_BIT_API_KEY}
  LOGTIDE_API_HOST: backend
depends_on:
  - backend
restart: unless-stopped
What Fluent Bit Does
  • Tails logs from /var/lib/docker/containers/*/*.log
  • Parses Docker JSON logs and extracts metadata
  • Adds container name, ID, and image as metadata
  • Sends to LogTide API with automatic retries (3x)
  • Flushes logs every 5 seconds

Fluent Bit Configuration (Advanced)

If you want to customize Fluent Bit or use it outside of LogTide's Docker Compose setup, here's the complete configuration:

fluent-bit.conf

Main configuration file for Fluent Bit. This collects Docker container logs and sends them to LogTide:

# Fluent Bit Configuration for LogTide

[SERVICE]
  # Flush logs every 5 seconds
  Flush        5
  # Run in foreground
  Daemon       Off
  # Log level (error, warning, info, debug, trace)
  Log_Level    info
  # Parsers configuration file
  Parsers_File /fluent-bit/etc/parsers.conf

# =============================================================================
# INPUT - Docker Container Logs
# =============================================================================
[INPUT]
  Name              tail
  Path              /var/lib/docker/containers/*/*.log
  Parser            docker
  Tag               docker.*
  Refresh_Interval  5
  Mem_Buf_Limit     5MB
  Skip_Long_Lines   On
  Path_Key          filepath

# =============================================================================
# FILTER - Parse and Enrich
# =============================================================================
# Extract container metadata (name, id, image)
[FILTER]
  Name                parser
  Match               docker.*
  Key_Name            log
  Parser            docker_json
  Reserve_Data        On
  Preserve_Key        On

# Add required fields for LogTide API
[FILTER]
  Name                modify
  Match               docker.*
  # Set default level if not present
  Add                 level info
  # Rename 'log' field to 'message'
  Rename              log message
  # Set service name from container_name
  Copy                container_name service

# Remove unnecessary fields to reduce log size
[FILTER]
  Name                record_modifier
  Match               docker.*
  Remove_key          stream
  Remove_key          filepath
  Remove_key          container_name

# =============================================================================
# OUTPUT - Send to LogTide
# =============================================================================
[OUTPUT]
  Name                http
  Match               docker.*
  Host                ${LOGTIDE_API_HOST}
  Port                8080
  URI                 /api/v1/ingest/single
  Format              json_lines
  Header              X-API-Key ${LOGTIDE_API_KEY}
  Header              Content-Type application/json
  # Date/time settings
  Json_date_key       time
  Json_date_format    iso8601
  # Retry settings
  Retry_Limit         3
  # TLS (disable for internal Docker network)
  tls                 Off

parsers.conf

Parser definitions for Docker JSON logs:

# Fluent Bit Parsers Configuration

# Parser for Docker JSON logs
[PARSER]
  Name        docker_json
  Format      json
  Time_Key    time
  Time_Format %Y-%m-%dT%H:%M:%S.%L%z
  Time_Keep   On

# Parser for Docker container logs
[PARSER]
  Name        docker
  Format      json
  Time_Key    time
  Time_Format %Y-%m-%dT%H:%M:%S.%L%z
  Time_Keep   On

extract_container_id.lua (Optional)

Lua script to extract container ID from file path (used in LogTide's setup for metadata enrichment):

-- Extract container ID from Docker log file path
-- Path format: /var/lib/docker/containers/<container_id>/<container_id>-json.log

function extract_container_id(tag, timestamp, record)
  local filepath = record["filepath"]

  if filepath == nil then
      return 0, timestamp, record
  end

  -- Extract container ID from path
  -- Example: /var/lib/docker/containers/abc123.../abc123...-json.log
  local container_id = filepath:match("/var/lib/docker/containers/([^"]+)/", 1)

  if container_id then
      record["container_id"] = container_id
      record["container_short_id"] = container_id:sub(1, 12)
  end

  -- Return code: 1 = modified and keep, 0 = no change
  return 1, timestamp, record
end

Usage with docker-compose.yml

If you want to add Fluent Bit to your own project (not using LogTide's Docker Compose):

services:
  fluent-bit:
    image: fluent/fluent-bit:4.2.2  # For ARM64/Raspberry Pi: cr.fluentbit.io/fluent/fluent-bit:4.2.2
    container_name: my-fluent-bit
    volumes:
      # Mount configuration files
      - ./fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf:ro
      - ./parsers.conf:/fluent-bit/etc/parsers.conf:ro
      # Optional: Lua scripts for advanced processing
      - ./extract_container_id.lua:/fluent-bit/etc/extract_container_id.lua:ro
      # Docker logs directory (read-only)
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      # Docker socket (read-only)
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      # For LogTide Cloud
      LOGTIDE_API_KEY: lp_your_api_key_here
      LOGTIDE_API_HOST: api.logtide.dev

      # Or for self-hosted
      # LOGTIDE_API_KEY: lp_your_api_key_here
      # LOGTIDE_API_HOST: localhost  # or your server IP
    restart: unless-stopped
    networks:
      - your-network

networks:
  your-network:
    driver: bridge

Important Notes

  • • Fluent Bit needs access to /var/lib/docker/containers to read container logs
  • • The LOGTIDE_API_KEY environment variable is used in the configuration via $