Collect an OpenShift project report with oc
A read-only bash script that gathers a project's workloads, pods, routes, builds, storage and warning events, plus describe output and logs of unhealthy pods, into a folder for a ticket.
Not checked by a trusted editor yet Last edited Outdated?
What this changes
Creates a local report folder (default ./report-PROJECT-TIMESTAMP, or -o DIR) with text output of oc get, describe and logs. It only reads from the cluster; nothing in OpenShift is changed.
How to undo it
Delete the folder, e.g. rm -rf ./report-shop-dev-*. Logs and config.txt can reveal internal details, so review them before sharing.
When an app misbehaves, the first ten minutes go into running the same oc get and oc describe commands. This script runs them all for one project and writes the output into a folder you can read, diff or attach to a ticket. It only reads: it never edits, scales or deletes anything.
The script
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<USAGE
Usage: $(basename "$0") [-n PROJECT] [-o OUTPUT_DIR] [-l LOG_LINES]
Collects a read-only report of one OpenShift project with oc.
-n PROJECT project to inspect (default: the current oc project)
-o OUTPUT_DIR where to write the report (default: ./report-PROJECT-TIMESTAMP)
-l LOG_LINES log lines to keep per problem pod (default: 100)
USAGE
}
PROJECT=""
OUT=""
LOG_LINES=100
while getopts ":n:o:l:h" opt; do
case "$opt" in
n) PROJECT=$OPTARG ;;
o) OUT=$OPTARG ;;
l) LOG_LINES=$OPTARG ;;
h) usage; exit 0 ;;
:) echo "option -$OPTARG needs a value" >&2; usage >&2; exit 2 ;;
\?) echo "unknown option -$OPTARG" >&2; usage >&2; exit 2 ;;
esac
done
command -v oc >/dev/null 2>&1 || { echo "oc not found in PATH" >&2; exit 1; }
oc whoami >/dev/null 2>&1 || { echo "not logged in: run oc login first" >&2; exit 1; }
if [[ -z "$PROJECT" ]]; then
PROJECT=$(oc config view --minify -o jsonpath='{..namespace}')
[[ -n "$PROJECT" ]] || { echo "no current project: pass -n PROJECT" >&2; exit 1; }
fi
STAMP=$(date '+%Y%m%d-%H%M%S')
OUT=${OUT:-"./report-$PROJECT-$STAMP"}
mkdir -p "$OUT/logs"
run() {
local file=$1; shift
{
echo "\$ $*"
"$@" 2>&1 || echo "(command failed or not permitted)"
echo
} >> "$OUT/$file"
}
{
echo "Project report: $PROJECT"
echo "Generated: $(date '+%Y-%m-%d %H:%M:%S %z')"
echo "User: $(oc whoami)"
echo "Server: $(oc config view --minify -o jsonpath='{.clusters[0].cluster.server}')"
echo
} > "$OUT/summary.txt"
run summary.txt oc status -n "$PROJECT"
run workloads.txt oc get deployments,statefulsets,daemonsets -n "$PROJECT" -o wide
run workloads.txt oc get pods -n "$PROJECT" -o wide
run networking.txt oc get services -n "$PROJECT" -o wide
run networking.txt oc get routes -n "$PROJECT"
run builds.txt oc get buildconfigs,builds -n "$PROJECT"
run builds.txt oc get imagestreams -n "$PROJECT"
run storage.txt oc get pvc -n "$PROJECT"
run config.txt oc get configmaps,secrets -n "$PROJECT"
run events.txt oc get events -n "$PROJECT" --sort-by=.lastTimestamp
run events.txt oc get events -n "$PROJECT" --field-selector type=Warning --sort-by=.lastTimestamp
PROBLEM_PODS=$(oc get pods -n "$PROJECT" \
-o jsonpath='{range .items[*]}{.metadata.name}{" "}{.status.phase}{" "}{range .status.containerStatuses[*]}{.ready}{","}{end}{"\n"}{end}' \
| awk '$2 != "Succeeded" && ($2 != "Running" || $3 ~ /false/) { print $1 }')
if [[ -z "$PROBLEM_PODS" ]]; then
echo "No problem pods found." >> "$OUT/summary.txt"
else
echo "Problem pods:" >> "$OUT/summary.txt"
for pod in $PROBLEM_PODS; do
echo " $pod" >> "$OUT/summary.txt"
run "logs/$pod.describe.txt" oc describe pod "$pod" -n "$PROJECT"
run "logs/$pod.log" oc logs "$pod" -n "$PROJECT" --all-containers --tail="$LOG_LINES"
run "logs/$pod.previous.log" oc logs "$pod" -n "$PROJECT" --all-containers --previous --tail="$LOG_LINES"
done
fi
echo "Report written to $OUT"
Usage
chmod +x project-report.sh
oc login https://api.cluster.example.com:6443 -u developer
./project-report.sh # current project
./project-report.sh -n shop-dev -l 300 # another project, more log lines
./project-report.sh -n shop-dev -o /tmp/shop-report
What you get
summary.txt: who ran it, against which API server,oc statusand the list of problem pods.workloads.txt,networking.txt,builds.txt,storage.txt,config.txt: deployments, pods, services, routes, builds, image streams, PVCs, and ConfigMap and Secret names.events.txt: all events sorted by time, then only warnings.logs/: for every pod that is not Running and ready (and not Succeeded), itsoc describeoutput, current logs and logs of the previous, crashed container.
How it decides a pod is a problem
A JSONPath query prints each pod’s name, phase and the readiness of each container. awk keeps pods that are not Succeeded and are either not Running or have a container with ready=false. That catches Pending, CrashLoopBackOff (phase Running but not ready) and failed pods.
Notes
- You only need
viewrights in the project. Commands you are not allowed to run are recorded as failed instead of stopping the script. - Secret contents are never read, only their names. Logs can still contain sensitive data, so check the folder before sharing it.
- Events are kept for a limited time by the cluster, so run the script soon after a problem happens.
Official documentation
See also
- 0150 Logging in with oc and working with OpenShift projects Install the oc client, log in with a password, browser or token, then create, switch and inspect projects. Covers where oc stores… Beginner · How-to · Any system Article Concepts · Deploying applications 15 Oct 2026
- 0151 Tutorial: deploy a small web app on OpenShift and expose it with a Route A step-by-step first deployment: create a project, build a static website from Git with Source-to-Image, publish it on an HTTPS Route, then… Beginner · How-to · Any system Article Deploying applications 15 Oct 2026
- 0152 Build and deploy from source with oc new-app and Source-to-Image How oc new-app turns a Git repository or an image into a running app, how Source-to-Image and Docker builds are chosen, and… Intermediate · How-to · Any system Article Deploying applications 15 Oct 2026
- 0153 Expose apps with OpenShift Routes: edge, passthrough and re-encrypt TLS A Route publishes a service on a host name through the OpenShift router. Learn when to use plain HTTP, edge, passthrough or… Intermediate · How-to · Any system Article Deploying applications · Ingress & networking 15 Oct 2026
- 0154 OpenShift app configuration: environment, ConfigMaps, Secrets and persistent storage Set environment variables, load ConfigMaps and Secrets into a Deployment as variables or files, and give it persistent storage with a PersistentVolumeClaim,… Intermediate · How-to · Any system Article Config, secrets & storage · Deploying applications 15 Oct 2026
- 0157 oc cheat sheet: everyday OpenShift CLI commands The oc commands you use every day, grouped by task: login and projects, apps and builds, routes, config, debugging, permissions and admin… Intermediate · Reference · Any system Article Deploying applications · Troubleshooting 15 Oct 2026
Repos in the wild
- openshift/oc: the OpenShift command line client openshift/oc Source code of oc, the OpenShift CLI. It is built on top of kubectl, so it can do everything kubectl does, and adds commands for projects, builds, routes, image streams and cluster administration. GitHub
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Commitpedia +5,679 chars