---
title: Logs
description: Everything your containers print, searchable in the console and followed from the CLI.
order: 1
---

Ops collects what every container of your project prints to stdout and stderr. There is
nothing to install and nothing to configure.

## Write JSON lines

A plain line is kept as its message. A line that is a JSON object is read field by field,
and these fields are kept:

| field | used for |
| --- | --- |
| `level` | the level filter: `ERROR`, `WARN`, `INFO`, `DEBUG` |
| `message`, or `fields.message` | the text |
| `target` | where in the code it came from |
| `fields.route`, `fields.status`, `fields.method` | the request it belongs to; `route` may also sit at the top |

`status` and `method` count only inside `fields`, the way a tracing subscriber nests a
line's fields. Any other field is dropped before it is stored. Email addresses, card numbers, tokens and
similar values in a message are masked. Still, never log a password or a person's data on
purpose.

With the Rust `ops-sdk`, set `LOG_FORMAT=json` in the service's secret group and the
subscriber writes exactly this shape.

## In the console

**Logs** shows the environment picked in the sidebar, newest first, with a histogram over
the range. Filter by service, level, a search text and a time range; the filters apply as
you change them.

## From a terminal

```sh
ops logs                          # the latest 200 lines
ops logs --level ERROR --since 1h
ops logs --grep timeout --limit 1000
ops logs -f                       # follow, Ctrl+C to stop
ops logs -f --env staging
```

| flag | what it does |
| --- | --- |
| `--service <name>` | one service, written as the service column of the output shows it |
| `--level <level>` | one level |
| `--grep <text>` | lines whose message holds the text |
| `--since <time>` | from a duration ago, such as `30s`, `5m`, `2h` or `7d`, or from an RFC 3339 time |
| `--limit <n>` | at most n lines, 1 to 1000 |
| `--env <name>` | another environment than production |
| `-f` | keep following new lines |
| `--interval <secs>` | how often `-f` asks, default 2 |

`ops logs` reads the project chosen with `ops use`. Pipe it into `grep` or `awk`: every
line is the time, the level, the service and the message.
