Loki LogCLI

logcli cheatsheet — query Loki logs with LogQL. logcli query '{app="nginx"}', logcli labels, logcli series. Explore logs from the terminal without Grafana UI.

6 min read

What it is

Loki’s official command-line interface for querying logs, managing the Loki instance, and interacting with its data. You reach for logcli when you need to explore logs directly from your terminal, debug issues, or automate log-related tasks.

Installation

Linux (using binaries)

curl -s https://grafana.com/get/loki/logcli | sudo bash
# logcli will be installed to /usr/local/bin/logcli

macOS (using Homebrew)

brew install grafana/tap/logcli

Windows (using Scoop)

scoop install logcli

From Source

Refer to the official Loki documentation for building from source.

Core Concepts

  • Labels: Loki indexes logs by labels, similar to Prometheus. These labels are key-value pairs that allow you to filter and select specific log streams. Examples: app="myapp", level="error", host="server1".
  • Log Streams: A set of logs that share the same set of labels.
  • LogQL: Loki’s query language, used to filter and search log content. It supports label selectors and a rich set of functions for parsing and analyzing log content.

Commands / Usage

Querying Logs

  • Tail logs in real-time:

    logcli --addr="http://localhost:3100" tail '{app="myapp", level="info"}'
    

    Tails logs matching the label selector {app="myapp", level="info"}.

  • Query logs within a time range:

    logcli --addr="http://localhost:3100" query --since="1h" '{app="myapp", level="error"}'
    

    Queries logs matching {app="myapp", level="error"} from the last hour.

  • Query logs with specific time frame (start and end):

    logcli --addr="http://localhost:3100" query --from="2023-10-27T10:00:00Z" --to="2023-10-27T11:00:00Z" '{app="myapp"}'
    

    Queries logs for app="myapp" between 10:00 AM and 11:00 AM UTC on October 27, 2023.

  • Query with LogQL content filtering:

    logcli --addr="http://localhost:3100" query '{app="myapp"}' | logcli --addr="http://localhost:3100" query --since="5m" 'level="error" and "database connection failed"'
    

    First, queries all logs for app="myapp", then filters those results for entries containing "database connection failed" and occurring in the last 5 minutes.

  • Query with LogQL parsing and filtering (JSON logs):

    logcli --addr="http://localhost:3100" query '{app="api-service"}' | logcli --addr="http://localhost:3100" query 'json | __line__ | "user_id" == "123"'
    

    Queries logs for app="api-service", parses them as JSON, and filters for logs where the user_id field is "123".

  • Query with LogQL parsing and filtering (regex logs):

    logcli --addr="http://localhost:3100" query '{app="nginx-ingress"}' | logcli --addr="http://localhost:3100" query '(?P<remote_addr>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*GET\s+(?P<request_path>\S+)' | logcli --addr="http://localhost:3100" query 'request_path=~"/admin/.*"'
    

    Queries Nginx ingress logs, extracts remote address and request path using regex, and then filters for requests to paths starting with /admin/.

  • Get unique label values:

    logcli --addr="http://localhost:3100" labels app
    

    Lists all unique values for the app label.

  • Get unique label values for a specific stream:

    logcli --addr="http://localhost:3100" labels app --from="{host=\"server1\"}"
    

    Lists unique app label values for logs originating from host="server1".

  • Get all available label names:

    logcli --addr="http://localhost:3100" labels
    

    Lists all label names present in Loki.

  • Get all unique values for all labels:

    logcli --addr="http://localhost:3100" labels --all
    

    Lists unique values for all labels.

Managing Loki

  • Check Loki status:

    logcli --addr="http://localhost:3100" status
    

    Displays information about the Loki instance’s health and configuration.

  • List all configured tenants (if multi-tenancy is enabled):

    logcli --addr="http://localhost:3100" tenants
    

    Lists all tenants known to the Loki instance.

Configuration

  • Show current configuration:
    logcli --config.file="/path/to/loki-config.yaml" config show
    
    Displays the active configuration loaded from the specified file.

Output Formatting

  • Output logs in JSON format:

    logcli --addr="http://localhost:3100" --output=json query '{app="myapp"}'
    

    Outputs query results as JSON objects.

  • Output logs in YAML format:

    logcli --addr="http://localhost:3100" --output=yaml query '{app="myapp"}'
    

    Outputs query results as YAML objects.

  • Output logs in CSV format:

    logcli --addr="http://localhost:3100" --output=csv query '{app="myapp"}'
    

    Outputs query results as CSV.

Common Flags

  • --addr="<loki_address>": The address of the Loki instance (e.g., http://localhost:3100).
  • --since=<duration>: Queries logs from a relative duration ago (e.g., 1h, 30m, 5s).
  • --from=<timestamp>: Queries logs from a specific start timestamp (e.g., 2023-10-27T10:00:00Z).
  • --to=<timestamp>: Queries logs up to a specific end timestamp (e.g., 2023-10-27T11:00:00Z).
  • --limit=<number>: Limits the number of log lines returned by a query.
  • --output=<format>: Sets the output format (e.g., json, yaml, csv, table).
  • --config.file=<path>: Path to the logcli configuration file.
  • --tenant=<tenant_id>: Specifies the tenant ID for multi-tenant Loki instances.

Common Patterns

  • Finding recent errors across all applications:

    logcli --addr="http://localhost:3100" query --since="15m" '{level="error"}'
    

    Searches for any log entry with the label level="error" within the last 15 minutes.

  • Searching for a specific error message and its context:

    logcli --addr="http://localhost:3100" query --since="30m" '{app="backend"}' | logcli --addr="http://localhost:3100" query 'database connection timed out' --limit=10
    

    First, gets all logs from the backend app in the last 30 minutes, then filters those results for lines containing "database connection timed out" and shows the first 10 matching lines.

  • Extracting specific fields from JSON logs and filtering:

    logcli --addr="http://localhost:3100" query '{app="api-gateway"}' | logcli --addr="http://localhost:3100" query 'json | request_time > 500'
    

    Queries logs from api-gateway, parses them as JSON, and filters for logs where the request_time field is greater than 500.

  • Finding logs related to a specific user ID and showing surrounding logs:

    logcli --addr="http://localhost:3100" query --since="1h" '{app="auth-service"}' | logcli --addr="http://localhost:3100" query 'user_id="abcdef123"' --limit=20
    

    Retrieves logs from the auth-service in the last hour, filters for lines containing user_id="abcdef123", and displays up to 20 matching lines.

  • Counting occurrences of a specific error message:

    logcli --addr="http://localhost:3100" query --since="24h" '{app="frontend"}' | logcli --addr="http://localhost:3100" query 'login failed' | wc -l
    

    Queries logs from frontend in the last 24 hours, filters for "login failed", and then uses wc -l to count the number of matching lines.

  • Getting log streams for a specific host and namespace:

    logcli --addr="http://localhost:3100" ls --since="1h" '{host="webserver-01", namespace="production"}'
    

    Lists the log streams (label sets) that match the specified criteria from the last hour.

Gotchas

  • Timestamp Precision: Loki’s timestamps are highly precise. When using --from and --to, ensure you use the correct format (ISO 8601 with timezone, e.g., 2023-10-27T10:00:00Z).
  • LogQL Syntax: LogQL can be powerful but has its own syntax. Incorrectly formatted LogQL queries will result in no logs being returned or errors. Pay close attention to quotes, operators (=, !=, =~, !~), and function calls.
  • Label Selectors vs. Content Search: Remember that label selectors ({app="myapp"}) are applied before content filtering ("error message"). If a log doesn’t match the label selector, its content won’t even be searched.
  • Performance with Large Datasets: Querying vast amounts of logs without specific label selectors can be slow and resource-intensive. Always try to narrow down your search using labels first.
  • Default Loki Address: If --addr is not specified, logcli defaults to http://localhost:3100. Ensure this matches your Loki instance’s address.
  • Rate Limiting: If you’re making many requests rapidly, you might encounter rate limiting from the Loki server.
  • ls vs query: The ls command lists log streams (label sets), while query retrieves actual log lines. Use ls to discover available streams and query to inspect their content.