Home

Awesome

Build

stern

Fork of discontinued wercker/stern

Stern allows you to tail multiple pods on Kubernetes and multiple containers within the pod. Each result is color coded for quicker debugging.

The query is a regular expression or a Kubernetes resource in the form <resource>/<name> so the pod name can easily be filtered and you don't need to specify the exact id (for instance omitting the deployment id). If a pod is deleted it gets removed from tail and if a new pod is added it automatically gets tailed.

When a pod contains multiple containers Stern can tail all of them too without having to do this manually for each one. Simply specify the container flag to limit what containers to show. By default all containers are listened to.

Installation

Download binary

Download a binary release

Build from source

go install github.com/stern/stern@latest

asdf (Linux/macOS)

If you use asdf, you can install like this:

asdf plugin-add stern
asdf install stern latest

Homebrew (Linux/macOS)

If you use Homebrew, you can install like this:

brew install stern

Krew (Linux/macOS/Windows)

If you use Krew which is the package manager for kubectl plugins, you can install like this:

kubectl krew install stern

Usage

stern pod-query [flags]

The pod-query is a regular expression or a Kubernetes resource in the form <resource>/<name>.

The query is a regular expression when it is not a Kubernetes resource, so you could provide "web-\w" to tail web-backend and web-frontend pods but not web-123.

When the query is in the form <resource>/<name> (exact match), you can select all pods belonging to the specified Kubernetes resource, such as deployment/nginx. Supported Kubernetes resources are pod, replicationcontroller, service, daemonset, deployment, replicaset, statefulset and job.

cli flags

<!-- auto generated cli flags begin --->
flagdefaultpurpose
--all-namespaces, -AfalseIf present, tail across all namespaces. A specific namespace is ignored even if specified with --namespace.
--colorautoForce set color output. 'auto': colorize if tty attached, 'always': always colorize, 'never': never colorize.
--completionOutput stern command-line completion code for the specified shell. Can be 'bash', 'zsh' or 'fish'.
--config~/.config/stern/config.yamlPath to the stern config file
--container, -c.*Container name when multiple containers in pod. (regular expression)
--container-colorsSpecifies the colors used to highlight container names. Use the same format as --pod-colors. Defaults to the values of --pod-colors if omitted, and must match its length.
--container-stateallTail containers with state in running, waiting, terminated, or all. 'all' matches all container states. To specify multiple states, repeat this or set comma-separated value.
--contextThe name of the kubeconfig context to use
--diff-container, -dfalseDisplay different colors for different containers.
--ephemeral-containerstrueInclude or exclude ephemeral containers.
--exclude, -e[]Log lines to exclude. (regular expression)
--exclude-container, -E[]Container name to exclude when multiple containers in pod. (regular expression)
--exclude-pod[]Pod name to exclude. (regular expression)
--field-selectorSelector (field query) to filter on. If present, default to ".*" for the pod-query.
--highlight, -H[]Log lines to highlight. (regular expression)
--include, -i[]Log lines to include. (regular expression)
--init-containerstrueInclude or exclude init containers.
--kubeconfigPath to the kubeconfig file to use for CLI requests.
--max-log-requests-1Maximum number of concurrent logs to request. Defaults to 50, but 5 when specifying --no-follow
--namespace, -nKubernetes namespace to use. Default to namespace configured in kubernetes context. To specify multiple namespaces, repeat this or set comma-separated value.
--no-followfalseExit when all logs have been shown.
--nodeNode name to filter on.
--only-log-linesfalsePrint only log lines
--output, -odefaultSpecify predefined template. Currently support: [default, raw, json, extjson, ppextjson]
--pod-colorsSpecifies the colors used to highlight pod names. Provide colors as a comma-separated list using SGR (Select Graphic Rendition) sequences, e.g., "91,92,93,94,95,96".
--prompt, -pfalseToggle interactive prompt for selecting 'app.kubernetes.io/instance' label values.
--selector, -lSelector (label query) to filter on. If present, default to ".*" for the pod-query.
--show-hidden-optionsfalsePrint a list of hidden options.
--since, -s48h0m0sReturn logs newer than a relative duration like 5s, 2m, or 3h.
--stdinfalseParse logs from stdin. All Kubernetes related flags are ignored when it is set.
--tail-1The number of lines from the end of the logs to show. Defaults to -1, showing all logs.
--templateTemplate to use for log lines, leave empty to use --output flag.
--template-file, -TPath to template to use for log lines, leave empty to use --output flag. It overrides --template option.
--timestamps, -tPrint timestamps with the specified format. One of 'default' or 'short' in the form '--timestamps=format' ('=' cannot be omitted). If specified but without value, 'default' is used.
--timezoneLocalSet timestamps to specific timezone.
--verbosity0Number of the log level verbosity
--version, -vfalsePrint the version and exit.
<!-- auto generated cli flags end --->

See stern --help for details

Stern will use the $KUBECONFIG environment variable if set. If both the environment variable and --kubeconfig flag are passed the cli flag will be used.

config file

You can use the config file to change the default values of stern options. The default config file path is ~/.config/stern/config.yaml.

# <flag name>: <value>
tail: 10
max-log-requests: 999
timestamps: short

You can change the config file path with --config flag or STERNCONFIG environment variable.

templates

stern supports outputting custom log messages. There are a few predefined templates which you can use by specifying the --output flag:

outputdescription
defaultDisplays the namespace, pod and container, and decorates it with color depending on --color
rawOnly outputs the log message itself, useful when your logs are json and you want to pipe them to jq
jsonMarshals the log struct to json. Useful for programmatic purposes
extjsonOutputs extended JSON with colorized pod/container names
ppextjsonPretty-prints extended JSON with colorized pod/container names

It accepts a custom template through the --template flag, which will be compiled to a Go template and then used for every log message. This Go template will receive the following struct:

propertytypedescription
MessagestringThe log message itself
NodeNamestringThe node name where the pod is scheduled on
NamespacestringThe namespace of the pod
PodNamestringThe name of the pod
ContainerNamestringThe name of the container

The following functions are available within the template (besides the builtin functions):

funcargumentsdescription
jsonobjectMarshal the object and output it as a json text
colorcolor.Color, stringWrap the text in color (.ContainerColor and .PodColor provided)
parseJSONstringParse string as JSON
tryParseJSONstringAttempt to parse string as JSON, return nil on failure
extractJSONPartsstring, ...stringParse string as JSON and concatenate the given keys.
tryExtractJSONPartsstring, ...stringAttempt to parse string as JSON and concatenate the given keys. , return text on failure
prettyJSONanyParse input and emit it as pretty printed JSON, if parse fails output string as is.
toRFC3339NanoobjectParse timestamp (string, int, json.Number) and output it using RFC3339Nano format
toTimestampobject, string [, string]Parse timestamp (string, int, json.Number) and output it using the given layout in the timezone that is optionally given (defaults to UTC).
levelColorstringPrint log level using appropriate color
bunyanLevelColorstringPrint bunyan numeric log level using appropriate color
colorBlackstringPrint text using black color
colorRedstringPrint text using red color
colorGreenstringPrint text using green color
colorYellowstringPrint text using yellow color
colorBluestringPrint text using blue color
colorMagentastringPrint text using magenta color
colorCyanstringPrint text using cyan color
colorWhitestringPrint text using white color

Log level verbosity

You can configure the log level verbosity by the --verbosity flag. It is useful when you want to know how stern interacts with a Kubernetes API server in troubleshooting.

Increasing the verbosity increases the number of logs. --verbosity 6 would be a good starting point.

Max log requests

Stern has the maximum number of concurrent logs to request to prevent unintentional load to a cluster. The number can be configured by the --max-log-requests flag.

The behavior and the default are different depending on the presence of the --no-follow flag.

--no-followdefaultbehavior
specified5limits the number of concurrent logs to request
not specified50exits with an error when if it reaches the concurrent limit

The combination of --max-log-requests 1 and --no-follow will be helpful if you want to show logs in order.

Customize highlight colors

You can configure highlight colors for pods and containers in the config file using a comma-separated list of SGR (Select Graphic Rendition) sequences, as shown below. If you omit container-colors, the pod colors will be used as container colors as well.

# Green, Yellow, Blue, Magenta, Cyan, White
pod-colors: "32,33,34,35,36,37"

# Colors with underline (4)
# If empty, the pod colors will be used as container colors
container-colors: "32;4,33;4,34;4,35;4,36;4,37;4"

This format enables the use of various attributes, such as underline, background colors, 8-bit colors, and 24-bit colors, if your terminal supports them.

The equivalent flags --pod-colors and --container-colors are also available. The following command applies 24-bit colors using the --pod-colors flag.

# Monokai theme
podColors="38;2;255;97;136,38;2;169;220;118,38;2;255;216;102,38;2;120;220;232,38;2;171;157;242"
stern --pod-colors "$podColors" deploy/app

Examples:

Tail all logs from all namespaces

stern . --all-namespaces

Tail the kube-system namespace without printing any prior logs

stern . -n kube-system --tail 0

Tail the gateway container running inside of the envvars pod on staging

stern envvars --context staging --container gateway

Tail the staging namespace excluding logs from istio-proxy container

stern -n staging --exclude-container istio-proxy .

Tail the kube-system namespace excluding logs from kube-apiserver pod

stern -n kube-system --exclude-pod kube-apiserver .

Show auth activity from 15min ago with timestamps

stern auth -t --since 15m

Show all logs of the last 5min by time, sorted by time

stern --since=5m --no-follow --only-log-lines -A -t . | sort -k4

Show auth activity with timestamps in specific timezone (default is your local timezone)

stern auth -t --timezone Asia/Tokyo

Follow the development of some-new-feature in minikube

stern some-new-feature --context minikube

View pods from another namespace

stern kubernetes-dashboard --namespace kube-system

Tail the pods filtered by run=nginx label selector across all namespaces

stern --all-namespaces -l run=nginx

Follow the frontend pods in canary release

stern frontend --selector release=canary

Tail the pods on kind-control-plane node across all namespaces

stern --all-namespaces --field-selector spec.nodeName=kind-control-plane

Tail the pods created by deployment/nginx

stern deployment/nginx

Pipe the log message to jq:

stern backend -o json | jq .

Only output the log message itself:

stern backend -o raw

Output using a custom template:

stern --template '{{printf "%s (%s/%s/%s/%s)\n" .Message .NodeName .Namespace .PodName .ContainerName}}' backend

Output using a custom template with stern-provided colors:

stern --template '{{.Message}} ({{.Namespace}}/{{color .PodColor .PodName}}/{{color .ContainerColor .ContainerName}}){{"\n"}}' backend

Output using a custom template with parseJSON:

stern --template='{{.PodName}}/{{.ContainerName}} {{with $d := .Message | parseJSON}}[{{$d.level}}] {{$d.message}}{{end}}{{"\n"}}' backend

Output using a custom template that tries to parse JSON or fallbacks to raw format:

stern --template='{{.PodName}}/{{.ContainerName}} {{ with $msg := .Message | tryParseJSON }}[{{ colorGreen (toRFC3339Nano $msg.ts) }}] {{ levelColor $msg.level }} ({{ colorCyan $msg.caller }}) {{ $msg.msg }}{{ else }} {{ .Message }} {{ end }}{{"\n"}}' backend

Pretty print JSON (if it is JSON) and output it:

# Will try to parse .Message as JSON and pretty print it, if not json will output as is
stern --template='{{ .Message | prettyJSON }}{{"\n"}}' backend
# Or with parsed json, will drop non-json logs because of `with`
stern --template='{{ with $msg := .Message | tryParseJSON }}{{ prettyJSON $msg }}{{"\n"}}{{end}}' backend

Load custom template from file:

stern --template-file=~/.stern.tpl backend

Trigger the interactive prompt to select an 'app.kubernetes.io/instance' label value:

stern -p

Output log lines only:

stern . --only-log-lines

Read from stdin:

stern --stdin < service.log

Completion

Stern supports command-line auto completion for bash, zsh or fish. stern --completion=(bash|zsh|fish) outputs the shell completion code which work by being evaluated in .bashrc, etc for the specified shell. In addition, Stern supports dynamic completion for --namespace, --context, --node, a resource query in the form <resource>/<name>, and flags with pre-defined choices.

If you use bash, stern bash completion code depends on the bash-completion. On the macOS, you can install it with homebrew as follows:

# If running Bash 3.2
brew install bash-completion

# or, if running Bash 4.1+
brew install bash-completion@2

Note that bash-completion must be sourced before sourcing the stern bash completion code in .bashrc.

source "$(brew --prefix)/etc/profile.d/bash_completion.sh"
source <(stern --completion=bash)

If installed via Krew, use:

source <(kubectl stern --completion bash)
complete -o default -F __start_stern kubectl stern

If you use zsh, just source the stern zsh completion code in .zshrc.

source <(stern --completion=zsh)

if you use fish shell, just source the stern fish completion code.

stern --completion=fish | source

# To load completions for each session, execute once:
stern --completion=fish >~/.config/fish/completions/stern.fish

Running with container

You can also use stern using a container:

docker run ghcr.io/stern/stern --version

If you are using a minikube cluster, you need to run a container as follows:

docker run --rm -v "$HOME/.minikube:$HOME/.minikube" -v "$HOME/.kube:/$HOME/.kube" -e KUBECONFIG="$HOME/.kube/config" ghcr.io/stern/stern .

You can find image tags in https://github.com/orgs/stern/packages/container/package/stern.

Running in Kubernetes Pods

If you want to use stern in Kubernetes Pods, you need to create the following ClusterRole and bind it to ServiceAccount.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: stern
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "watch", "list"]

Contributing to this repository

Please see CONTRIBUTING for details.