Skip to main content
Kubernetes Dashboard provides a convenient interface for viewing and downloading container logs. This guide covers how to access logs, apply filters, and troubleshoot common issues.

Overview

Dashboard streams container logs directly from the Kubernetes API, offering:
  • Real-time log streaming
  • Historical log retrieval
  • Multi-container pod support
  • Download and filtering capabilities
  • Timestamp display
  • Log rotation handling
Logs are retrieved using the Kubernetes pods/log API endpoint with configurable limits to prevent memory issues.

Accessing Container Logs

There are multiple ways to access logs in Dashboard:
  1. Navigate to WorkloadsPods
  2. Click on a pod name
  3. Click the Logs icon in the action bar
  4. Select the container (if multiple containers exist)

Log Viewer Interface

The log viewer provides several controls:

Container Selection

For pods with multiple containers:
type PodContainerList struct {
    Containers []string
}
Use the dropdown to switch between:
  • Init containers: Containers that run during pod initialization
  • Application containers: Main application containers

Timestamp Toggle

Show or hide timestamps for each log line:
2026-03-05T10:30:45.123456789Z [INFO] Application started successfully
2026-03-05T10:30:46.234567890Z [INFO] Listening on port 8080

Previous Logs

View logs from crashed containers:
1

Enable Previous Logs

Check the “Previous” checkbox in the log viewer
2

Review Crash Logs

Examine logs from the container before it crashed
Previous logs are only available if the container was restarted due to a crash or termination. They’re lost when the pod is deleted.

Log Retrieval Implementation

Dashboard implements log retrieval with safeguards (modules/api/pkg/resource/container/logs.go:55-75):
func GetLogDetails(client kubernetes.Interface, namespace, podID string, 
    container string, logSelector *logs.Selection, usePreviousLogs bool) (*logs.LogDetails, error) {
    
    pod, err := client.CoreV1().Pods(namespace).Get(context.TODO(), podID, metaV1.GetOptions{})
    if err != nil {
        return nil, err
    }
    
    if len(container) == 0 {
        container = pod.Spec.Containers[0].Name
    }
    
    logOptions := mapToLogOptions(container, logSelector, usePreviousLogs)
    rawLogs, err := readRawLogs(client, namespace, podID, logOptions)
    if err != nil {
        return nil, err
    }
    
    details := ConstructLogDetails(podID, rawLogs, container, logSelector)
    return details, nil
}

Read Limits

To prevent out-of-memory errors, Dashboard enforces limits (modules/api/pkg/resource/container/logs.go:28-32):
// Maximum number of lines loaded from the apiserver
var lineReadLimit int64 = 5000

// Maximum number of bytes loaded from the apiserver  
var byteReadLimit int64 = 500000
From Beginning: Reads up to 500KB From End: Reads up to 5000 lines

Log Options

Dashboard configures log retrieval (modules/api/pkg/resource/container/logs.go:77-94):
func mapToLogOptions(container string, logSelector *logs.Selection, previous bool) *v1.PodLogOptions {
    logOptions := &v1.PodLogOptions{
        Container:  container,
        Follow:     false,
        Previous:   previous,
        Timestamps: true,
    }
    
    if logSelector.LogFilePosition == logs.Beginning {
        logOptions.LimitBytes = &byteReadLimit
    } else {
        logOptions.TailLines = &lineReadLimit
    }
    
    return logOptions
}

Log Selection Options

Dashboard supports flexible log viewing:

Position Selection

Shows the most recent log lines (up to 5000 lines).Use case: Viewing recent activity or current application state

Reference Point

View logs relative to a specific timestamp or line number:
type Selection struct {
    LogFilePosition   string  // "beginning" or "end"
    ReferencePoint    LogLineId
    OffsetFrom        int
    OffsetTo          int
}

Downloading Logs

Download logs for offline analysis:
1

Open Log Viewer

Navigate to the logs for your container
2

Click Download

Click the download icon in the log viewer toolbar
3

Save File

Logs are downloaded as a .txt file with timestamps

Log File Streaming

For large log files, Dashboard streams directly to avoid memory issues (modules/api/pkg/resource/container/logs.go:114-125):
func GetLogFile(client kubernetes.Interface, namespace, podID string, 
    container string, opts *v1.PodLogOptions) (io.ReadCloser, error) {
    
    logOptions := &v1.PodLogOptions{
        Container:  container,
        Follow:     false,
        Previous:   opts.Previous,
        Timestamps: opts.Timestamps,
    }
    
    logStream, err := openStream(client, namespace, podID, logOptions)
    return logStream, err
}
The stream is piped directly to the HTTP response, preventing memory exhaustion.

Log Format

Logs are displayed with optional timestamps:
2026-03-05T10:30:45.123456789Z [INFO] Starting application
2026-03-05T10:30:45.234567890Z [INFO] Loading configuration from /etc/config
2026-03-05T10:30:45.345678901Z [INFO] Connecting to database
2026-03-05T10:30:46.456789012Z [INFO] Database connection established
2026-03-05T10:30:46.567890123Z [INFO] Server listening on :8080

Log Line Processing

Dashboard parses and structures log data (modules/api/pkg/resource/container/logs.go:136-156):
func ConstructLogDetails(podID string, rawLogs string, container string, 
    logSelector *logs.Selection) *logs.LogDetails {
    
    parsedLines := logs.ToLogLines(rawLogs)
    logLines, fromDate, toDate, logSelection, lastPage := parsedLines.SelectLogs(logSelector)
    
    readLimitReached := isReadLimitReached(
        int64(len(rawLogs)), 
        int64(len(parsedLines)), 
        logSelector.LogFilePosition,
    )
    truncated := readLimitReached && lastPage
    
    info := logs.LogInfo{
        PodName:       podID,
        ContainerName: container,
        FromDate:      fromDate,
        ToDate:        toDate,
        Truncated:     truncated,
    }
    
    return &logs.LogDetails{
        Info:      info,
        Selection: logSelection,
        LogLines:  logLines,
    }
}

Common Use Cases

Debugging Application Errors

1

Identify Failed Pod

Navigate to the pod list and look for pods with error status
2

View Recent Logs

Open logs from the end to see recent error messages
3

Check Previous Logs

If the container crashed, enable “Previous” to see logs before the crash
4

Download for Analysis

Download logs to search for patterns or share with your team

Investigating Startup Issues

1

Select Beginning Position

View logs from the beginning of the container lifecycle
2

Review Initialization

Check init container logs for startup failures
3

Verify Configuration

Look for configuration loading errors or missing environment variables

Monitoring Application Activity

1

Enable Auto-Refresh

Manually refresh the log view to see new entries (auto-follow coming soon)
2

Filter by Container

Switch between containers to monitor different aspects of your application

Troubleshooting

Dashboard limits log retrieval to prevent memory issues:
  • From End: 5000 lines maximum
  • From Beginning: 500KB maximum
Use kubectl logs for complete log access:
kubectl logs <pod-name> -n <namespace> --tail=10000
Check RBAC permissions:
kubectl auth can-i get pods/log --as=system:serviceaccount:kubernetes-dashboard:kubernetes-dashboard -n <namespace>
Ensure your service account has the get permission for pods/log.
Previous logs are only retained until the pod is deleted. For persistent logging:
  • Use a log aggregation system (Fluentd, Filebeat)
  • Configure persistent log storage
  • Enable audit logging
Large log files take time to retrieve. Optimize by:
  • Reducing log verbosity
  • Implementing log rotation
  • Using structured logging
  • Configuring shorter retention periods

Best Practices

Implement JSON logging for better parsing and filtering:
{"timestamp":"2026-03-05T10:30:45Z","level":"INFO","message":"User logged in","user_id":123}
  • Production: INFO or WARNING
  • Staging: DEBUG
  • Development: TRACE/DEBUG
Prevent disk space issues by configuring container log rotation:
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
Dashboard logs are useful for quick debugging, but use dedicated log aggregation for:
  • Long-term retention
  • Advanced search and filtering
  • Alerting and analysis
  • Compliance and audit requirements

Limitations

Be aware of Dashboard log viewer limitations:
  • No live streaming: Logs don’t auto-refresh (manual refresh required)
  • Size limits: 5000 lines or 500KB maximum
  • No filtering: Text search requires downloading logs
  • Single container: View one container at a time
For advanced log analysis, integrate with tools like:
  • ELK Stack (Elasticsearch, Logstash, Kibana)
  • Grafana Loki
  • Splunk
  • Datadog

Next Steps

Shell Access

Execute commands in running containers

Monitoring Metrics

View resource utilization and performance data

Build docs developers (and LLMs) love