Skip to content

Read the logs

$ grim logs -f app

A page returns a 500, a queued job never seems to run, a container keeps restarting. Before you change anything, read what the containers said. grim logs prints the output of the project's services, the last hundred lines of each unless you ask for more, and with -f it stays open and keeps printing as new lines arrive.

With --remote the same question goes to a deployed server instead of your own stack.

Usage

$ grim logs                              # every service, last 100 lines each
$ grim logs -f app                       # follow the app container
$ grim logs horizon --tail=500           # further back, one service
$ grim logs -f app --remote=production   # the same, on the server
$ grim logs -f vite                      # the Vite dev server on your machine

Run it from the project directory. A service is named as in docker-compose.yml: app, nginx, redis, mailpit, and horizon and scheduler where the project uses them.

vite is the exception on your own machine. There the dev server is not a container: grim up runs it on the host and sends its output to .grim/vite.log, and grim logs vite reads that file, -f included. On a dev box, where vite is a compose service, it is a service like the others. grim logs without a service name shows the containers only.

Arguments and options

Show container logs

Usage

grim logs [-f|--follow] [-t|--tail TAIL] [--remote REMOTE] [--] [<service>]

Arguments

Argument Description
service Service name (optional)

Options

Option Description
-f, --follow Follow log output
-t, --tail=TAIL Number of lines to show (default: 100)
--remote=REMOTE Run on remote server (environment name, e.g. production)

What it actually does

Locally it is one command, docker compose logs --tail=100, with -f and the service name added when you gave them. The output is Docker's own: each line carries the name of the container it came from.

For vite it first asks docker compose config --services whether the project has a vite service. When it does not, or Docker is not running, it prints the last lines of .grim/vite.log itself. With -f it keeps reading the file until Ctrl+C. grim up opens the log of every new dev server with a line of its own, -- grim up <time> (<id>) --, and when that line changes -f goes on from the top of the new log.

With --remote it takes three steps.

  1. Finds the server. The project name comes from deploy.project in grim.json, or name. The host and path come from the registration grim server:add-project left in ~/.grim/servers.json for that environment. The path falls back to /opt/<project>, or /opt/<project>-<environment> for anything but production, which is the directory grim server:add-project makes.
  2. Connects as the deploy user over SSH.
  3. Runs docker compose logs in that directory with the same --tail, -f and service. Nothing on the server is changed.

Without -f a remote read is given 60 seconds. With -f it stays open until you press Ctrl+C.

Pitfalls

Locally, the Laravel log is not in here

Containers log what they print. On your machine Laravel writes its exceptions to storage/logs/laravel.log, a file in the project directory, and grim logs app shows the output of PHP-FPM, not that file. Open it in your editor. On a server it is the other way round. The .env that grim server:add-project writes sets LOG_CHANNEL=stderr, so grim logs app --remote=production is where the exceptions are, and there is no log file to look for.

--remote knows only servers you registered

Environment 'staging' not configured for project 'shop'. means ~/.grim/servers.json on this machine has no such entry. Unlike grim env:pull, this command does not read the host from grim.json. Register the project with grim server:add-project.

No .grim/vite.log here

Vite has not run in this directory: grim up has not been run yet, or it was run with --no-vite, or the project has no package.json. Run grim up.

Outside a project there is nothing to read

Locally the command hands over to Docker without checking where you are, so the error is Docker's: no configuration file provided: not found. Change into the project directory.

After it finishes

Once the line that matters is on screen, the usual next step is to go and look inside.

$ grim shell

For a server, the recipe Debug production walks the whole path from the symptom to the fix.

Recipes that use it