Skaffold tailing logs is a lot more than just kubectl logs -f; it’s about real-time, application-aware feedback that dramatically shortens the "code-deploy-observe" loop.

Let’s watch Skaffold tailing in action. Imagine a simple Go web server.

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
)

func handler(w http.ResponseWriter, r *http.Request) {
	hostname, _ := os.Hostname()
	log.Printf("Received request from %s for %s", r.RemoteAddr, r.URL.Path)
	fmt.Fprintf(w, "Hello from %s!\n", hostname)
}

func main() {
	http.HandleFunc("/", handler)
	log.Println("Starting web server on :8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

And here’s the skaffold.yaml to build and run it, with log tailing enabled:

apiVersion: skaffold/v4beta9
kind: Config
build:
  artifacts:
    - image: my-go-app
      docker:
        dockerfile: Dockerfile
deploy:
  kubectl:
    manifests:
      - k8s/deployment.yaml
profiles:
  - name: dev
    activation:
      - kubeContext: docker-desktop
    deploy:
      kubectl:
        manifests:
          - k8s/deployment.yaml
    portForward:
      - resourceType: pod
        port: 8080
        localPort: 8080
    # This is the magic!
    log:
      prefix: "[APP]"
      tail: true
      all: true

And a basic k8s/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app-container
          image: my-go-app
          ports:
            - containerPort: 8080

Now, when you run skaffold dev --profile dev, Skaffold does its thing: builds the image, deploys it, port-forwards, and then immediately starts tailing logs. You’ll see output like this interleaved with Skaffold’s build and deploy messages:

[09:30:15] Starting web server on :8080
[APP][09:30:15] Starting web server on :8080
[09:30:16] Received request from 10.1.2.3:54321 for /
[APP][09:30:16] Received request from 10.1.2.3:54321 for /

Notice the [APP] prefix. That’s Skaffold helping you distinguish your application’s logs from Skaffold’s own operational messages. The all: true in the log section tells Skaffold to tail logs from all containers in the pod, which is crucial for multi-container pods.

The primary problem Skaffold’s log tailing solves is the disconnect between making a code change, deploying it, and then figuring out if it actually worked or why it failed. Without it, you’d typically:

  1. Edit code.
  2. Run skaffold dev (or skaffold build + kubectl apply).
  3. Wait for deploy.
  4. Run kubectl logs <pod-name> -f.
  5. Switch back to your application, trigger an action.
  6. Watch the kubectl logs output.

With skaffold dev --profile dev, step 4 and 5 are integrated. As soon as the new code is running in the pod, its logs appear directly in your Skaffold terminal. If you made a mistake, you see the error immediately without context switching.

Internally, Skaffold uses the Kubernetes API’s log endpoint for each container in your deployed pods. When tail: true is set, it establishes a stream connection. The prefix is just prepended to each line received from the Kubernetes API before it’s printed to your console. The all: true flag iterates through all containers defined in the pod spec and sets up individual log streams for each.

The power here is not just seeing logs, but seeing them as they happen and correlated with Skaffold’s own lifecycle. If Skaffold detects a change and is rebuilding, you’ll see the old logs disappear (or be clearly demarcated) as the new pod spins up and starts streaming its fresh logs. This provides a seamless transition during development.

When all: true is configured in the log section of skaffold.yaml, Skaffold will attempt to tail logs from every container within a pod. This means if you have a sidecar (like a service mesh proxy or a log collector) running alongside your application container, you’ll see logs from both interleaved in your Skaffold output, prefixed according to their respective prefix configurations or with a generic identifier if no prefix is set. This can be incredibly useful for debugging interactions between your application and its supporting infrastructure within the same pod.

The next step after mastering log tailing is understanding how Skaffold can automatically trigger rebuilds and redeploys based on file changes, which is the core of the skaffold dev experience.

Want structured learning?

Take the full Skaffold course →