How to Copy Error Logs Without Grabbing Half the Console
Pasting a full terminal scrollback into Slack or a Jira ticket is a failure mode, not a debug technique. The reader has to scroll, scan for the actual error, ignore the bootstrap noise, and somehow reconstruct what the reporter was trying to do. The reader usually gives up. The ticket sits for three days. The reporter escalates. The maintainer asks for "the actual error, not the whole log". The cycle is predictable, and it is avoidable.
This guide is about copying the right amount of error log: enough to communicate the failure, not so much that the signal disappears. It is written for developers, SREs, and support engineers who regularly move error output from a terminal into a ticket, chat, or bug report. For neighbouring topics, see best clipboard habits for developers in 2026, stack traces, tokens, and the clipboard, and the VS Code built-in clipboard ring vs an OS manager comparison.
What an error log actually contains
A typical error log has five layers, only one of which matters for the reader.
| Layer | Example | Useful to paste? |
|---|---|---|
| Bootstrap | Starting service... Loading config from /etc/app.yaml... | No — assumes the reader does not know the service runs |
| Operational | Connected to database at db-prod-01 in 234ms | No — assumes the reader does not believe the DB connected |
| The error itself | panic: runtime error: index out of range [5] with length 3 | Yes |
| The stack trace | goroutine 1 [running]: main.process(...) at /src/app.go:42 | Yes — the relevant frames only |
| Shutdown | Gracefully shutting down... Connection closed. | No — the shutdown is a consequence, not a cause |
A useful paste contains the error itself and the relevant stack frames. Everything else is noise that makes the signal harder to find. A 500-line dump usually has 5 to 15 useful lines.
Selecting the relevant frames
For a Go panic, a Java stack trace, or a Python traceback, the relevant frames are the ones in the application code, not in the framework or standard library. Framework frames tell the reader "the framework was doing framework things", which is unsurprising. Application frames tell the reader "this line of our code failed", which is the actionable information.
Patterns:
- Python traceback — read from the bottom up. The last frame is where the error occurred. Include the last 3 to 5 frames, skipping
site-packages/andlib/python3.x/frames unless they are the actual failure point. - Java stack trace — the first
Caused by:chain is usually the root cause. Include that, plus the top 3 frames of the first occurrence. - Go panic — the first
goroutineblock, with the top 3 frames. Skip runtime frames (runtime/,reflect/) unless the panic is in the runtime itself. - Node.js — the stack trace is usually printed in order, with the failing frame at the top. Include the top 5 frames.
- .NET — the stack trace is printed top-down. Include the top 5 frames, skipping
System.andMicrosoft.frames unless the failure is in the framework.
For a stack trace that does not have obvious framework markers, include the frames that reference the project's own package or namespace. Those are the ones the reader can act on.
Trimming noise
Once the relevant frames are selected, trim the per-line noise:
- Timestamps —
2026-08-19T14:23:45.123Z [ERROR] ...becomes[ERROR] ...unless the timestamp pattern itself is the bug (e.g. logs arriving out of order). - Thread or goroutine IDs — keep if the bug is a race condition, drop otherwise.
- Log levels — keep
[ERROR]and[FATAL], drop[DEBUG]and[INFO]. - Hostnames and pod names — keep if the bug is host-specific, drop otherwise. For Kubernetes, see Docker IDs, Kube contexts, and pin hygiene for why yesterday's pod name is worse than none.
- Verbose context — many logging libraries attach a map of context fields. Keep the ones that vary between success and failure (e.g.
user_id,request_id); drop the ones that are constant (e.g.service=auth,env=prod).
The result should be a 5-to-15-line excerpt that a reader can scan in a few seconds.
Redacting secrets
Error logs frequently capture secrets by accident. A database connection error will print the connection string (including the password). A misconfigured auth header will print the bearer token. A failed request to a payment API will print the API key in the URL. None of these belong in chat or in a ticket.
Before copying, scan the excerpt for:
- Connection strings —
mongodb://user:pass@host,postgres://user:pass@host,redis://:pass@host - Bearer tokens —
Authorization: Bearer eyJ...,token: ... - AWS keys —
AKIA... - Generic API keys — long hex or base64 strings in fields named
key,secret,token,password,api_key - Private keys —
-----BEGIN ... PRIVATE KEY-----blocks
Replace with placeholders: mongodb://user:***@host, Authorization: Bearer <redacted>, AKIAEXAMPLE. The placeholder communicates "there was a secret here" without leaking the secret. For deeper coverage of secret patterns and rotation triggers, see stack traces, tokens, and the clipboard and API keys on the clipboard are an incident.
Pasting the excerpt
Once the excerpt is selected, trimmed, and redacted, paste it as a fenced code block, not as plain text. Fenced code blocks preserve formatting, prevent Slack from converting :42: into an emoji, and make the log scrollable instead of one long line.
In Slack, use triple backticks. In Jira, use the code block macro. In Markdown (GitHub, GitLab), use a fenced block with the language hint for syntax highlighting:
Traceback (most recent call last): File "src/auth/handlers.py", line 42, in login user = verify_token(token) File "src/auth/tokens.py", line 18, in verify_token raise InvalidTokenError("expired") auth.InvalidTokenError: expired
Add one line of context above the block: what you were doing when the error occurred, what you expected, what you got. That line is the bridge between the log and the reader.
When the full log is needed
Sometimes the reader does need the full log — for example, when a support engineer asks for it to feed into a log analysis tool, or when the relevant excerpt is genuinely unclear without surrounding context. In those cases, attach the log as a file, do not paste it into chat.
Patterns that work:
- Slack — upload the log as a file, share the link in the channel. Slack's snippet feature preserves formatting and is searchable.
- Jira — attach the log to the ticket. Do not paste it into the description.
- Email — attach the log as a
.logor.txtfile. Do not paste 500 lines into the email body. - GitHub issue — use a
<details>collapse tag so the log is present but not in the reader's face:
``html <details><summary>Full log</summary> <pre> ... log lines here ... </pre> </details> ``
The full log is a fallback, not the first choice. The first choice is the trimmed excerpt.
Tooling that helps
teein bash,Tee-Objectin PowerShell — captures terminal output to a file while still showing it on screen. Lets the developer paste a trimmed excerpt while keeping the full log on disk for follow-up.jqfor JSON logs — extracts the relevant fields from a structured log without manual trimming.jq 'select(.level=="error") | {message, stack_trace}'is faster than manual selection for NDJSON logs.bat(acatclone with syntax highlighting and line numbers) — useful for selecting line ranges from a log file before copying.- Slack snippet upload — preserves formatting and is searchable across the workspace.
A local clipboard shelf can hold the working excerpt while it is being assembled — the trimmed frames in one pin, the redacted version in another — but the destination is the ticket or the chat, not the shelf. The shelf is a staging area; the trimmed excerpt is the deliverable.
A worked example
Before (raw paste, 200 lines, includes a connection string with the password):
2026-08-19T14:23:45.001Z [INFO] Starting auth service version 2.3.1
2026-08-19T14:23:45.012Z [INFO] Loading config from /etc/auth/config.yaml
2026-08-19T14:23:45.234Z [INFO] Connected to database at mongodb://auth_user:s3cretP@ss@db-prod-01:27017/auth in 234ms
... 195 more lines ...
2026-08-19T14:23:46.891Z [ERROR] Failed to verify token: expired
Traceback (most recent call last):
File "/usr/lib/python3.11/site-packages/flask/app.py", line 1523, in full_dispatch_request
rv = self.preprocess_request()
File "/usr/lib/python3.11/site-packages/flask/app.py", line 1945, in preprocess_request
funcs = self.before_request_funcs.get(None, ())
File "src/auth/handlers.py", line 42, in login
user = verify_token(token)
File "src/auth/tokens.py", line 18, in verify_token
raise InvalidTokenError("expired")
auth.InvalidTokenError: expired
... 50 more lines of shutdown noise ...
After (trimmed, redacted, 8 lines, ready to paste):
[ERROR] Failed to verify token: expired Traceback (most recent call last): File "src/auth/handlers.py", line 42, in login user = verify_token(token) File "src/auth/tokens.py", line 18, in verify_token raise InvalidTokenError("expired") auth.InvalidTokenError: expired
The second version takes 20 seconds to assemble and communicates the failure in one read. The first version takes the reader 90 seconds to skim and still might not communicate the failure. The developer who pastes the second version gets a faster response and a more accurate diagnosis. That is the entire value of the discipline.
Related reading
- Stack Traces, Tokens, and the Clipboard
- VS Code: Built-In Clipboard Ring vs an OS Manager
- Best Clipboard Habits for Developers in 2026
- Clipboard Tools on Multi-Monitor Windows Setups
Sources
- Python documentation — Exceptions and tracebacks — official description of how Python tracebacks are structured, which frames are most informative, and how to read them
- Go documentation — Panics and stack traces — official Go blog post on panic semantics and how to read a Go stack trace
- Microsoft Learn — PowerShell Tee-Object — official documentation for the PowerShell cmdlet that captures terminal output to a file
- Slack — Format messages with code blocks — Slack's guidance on fenced code blocks, which preserve log formatting in chat
- GitHub — Attaching files to issues — GitHub's guidance on issue attachments and the
<details>collapse tag for long logs
Deepender Yadav is a B.Tech Computer Science Engineering student and software developer interested in building practical software and open-source projects.
GitHub · LinkedInCopy. Stack. Drop.
Transform your clipboard into an interactive edge shelf. Stack, pin, and drag assets into any app with zero friction.
Download for Windows Get from Microsoft Store
How to Install Guide · First 10 Minutes Guide · Drag & Drop Guide · Edge-Drop vs Win+V · Support
Free · Lightweight · Privacy First