Set up with the SDK
Instrument your application by hand with a Neatlogs SDK, then verify that one real run is ready to investigate.
At the end of this guide, you will have instrumented your application by hand and brought one real run into Neatlogs with enough detail to inspect its model calls, tools, retrieval, and final output.
Prefer not to edit the code yourself? Paste our prompt into your own coding agent with Instrument with coding agents, or run the wizard. Already have traces in Langfuse, LangSmith, Braintrust, Raindrop, Laminar, or Phoenix? Import them first and add native instrumentation later.
Choose a setup path
Instrument with coding agents
Paste one prompt into Claude Code, Codex, Cursor, or another agent in your repository.
Instrument with the Wizard
Run one command that detects your stack and instruments it.
Import existing traces
Best when production history already lives in another observability platform.
| Choose | When it is the better first move | What you get |
|---|---|---|
| Coding agent or wizard | You want instrumentation without writing it yourself | New runs sent as your application executes |
| SDK by hand (this page) | You want to control every line of instrumentation | New runs sent as your application executes |
| Import | You have a failure to investigate now | Existing traces copied into a Neatlogs project |
| Both | You want history and continuous coverage | Imported and native traces, identified by source |
Importing does not require you to replace your current platform. Instrumentation can also coexist with another exporter when your tracing setup supports it.
Before you begin
You need:
- a Neatlogs workspace and project;
- the project's API key from Settings → Project → API keys (anyone with access to the project can copy it);
- one application run you can recognize after it arrives.
Use a non-production test run first if your traces contain customer data. Review data controls before sending sensitive fields.
Instrument your application
Initialize Neatlogs once, then wrap the client you already use:
import os
import neatlogs
from openai import OpenAI
neatlogs.init(
api_key=os.environ["NEATLOGS_API_KEY"], # from Settings → Project → API keys
workflow_name="my-agent", # names the task this process runs
)
client = neatlogs.wrap(OpenAI())Calls through client are now captured and sent to your project.
Using an EU project? Set endpoint="https://eu.ingest.neatlogs.com" in neatlogs.init(). TypeScript and Go use the same URL in their endpoint / Endpoint init option. Pass the base URL without /v1/traces, and use the key from the EU dashboard at https://eu.app.neatlogs.com.
Don't use OpenAI? Follow the integration page for your library. Some use neatlogs.wrap(...); LangChain/LangGraph use a callback handler; OpenAI Agents uses a processor; Strands uses hooks. TypeScript likewise uses explicit helpers such as wrapOpenAI(...) rather than instrumentation keys. See Integrations.
For installation, Doctor checks, and grouping several calls under one trace, follow the Python SDK, TypeScript SDK, or Go SDK guide.
Bring in your first run
Select the destination project. Check the workspace and project switchers before copying a key. A project is the boundary for telemetry, access, and project-level configuration.
Check the installed SDK. Run SDK Doctor locally before you rely on the instrumentation. It needs no project key and sends nothing.
Produce one recognizable run. Use a distinctive test input, such as neatlogs setup check, so you can find it without guessing which request arrived. Short-lived scripts must flush or shut down the SDK before they exit.
Open Traces and find the run. Select the same project, widen the time range if necessary, and search for the workflow name or distinctive input.
Inspect the execution. Confirm that the root run, important child steps, inputs, outputs, status, and timing agree with what your application did.
What a healthy first trace looks like
A useful trace is not merely present. It should let another person reconstruct the execution:
- one coherent root represents the request or agent run;
- child spans represent meaningful model, tool, retrieval, or agent steps;
- span names describe operations rather than generic functions such as
run; - the final output is attached to the root or clearly identifiable final step;
- errors appear on the step that failed;
- model, token, cost, and duration fields appear when the source supplies them;
- workflow, environment, session, and end-user identifiers are stable where applicable.
A trace should expose the execution shape and let you open the step that produced the outcome.
Do not mark setup complete if you can see only a final string but not the model or tool steps needed to explain it. Improve the instrumentation or source mapping first.
What Neatlogs does with incoming telemetry
Neatlogs normalizes source data into traces and spans while retaining its project, workflow, and source identity. The result becomes available to search, detections, analytics, comments, Evals, and investigations. Collection is observational: it does not change the prompt, tools, or decisions in your agent.
Troubleshoot the first run
| Symptom | Check first |
|---|---|
| Nothing arrives | SDK Doctor, project key, region endpoint, active project, time range, and exporter flush |
| Several roots appear for one request | Trace context propagation across processes and workers |
| LLM or tool steps are missing | Whether the framework integration covers that library and code path |
| Run appears in the wrong project | The key used by the application, or the project selected when an import started |
| Process exits before sending | Flush or shutdown behavior for short-lived scripts |
| Sensitive content is visible | SDK redaction and Settings → Project → PII redaction before more traffic is sent |
Continue with Traces are not arriving for a systematic diagnosis.
Frequently asked questions
Should I import or instrument directly?
Import when historical evidence is the priority. Instrument when ongoing coverage and the richest execution structure are the priority. Using both is normal.
Will the same run be duplicated if I use both?
Imported and native telemetry remain identifiable by source, but two independent pipelines can still send the same execution. Avoid overlapping import windows or exporter paths when duplication matters.
Can I call init() more than once?
Calling init() again with the same configuration is idempotent. Calling it with conflicting configuration raises a configuration error until the SDK is shut down, so don't use a second init() to switch projects inside one process.
Does setup change how my agent runs?
Neatlogs observes exported telemetry. Instrumentation adds recording overhead, but detections and investigations do not alter the agent’s decisions.
What data can a trace contain?
Whatever your integration exports: prompts, outputs, tool arguments and results, retrieval content, timing, tokens, metadata, and identifiers. You control what is emitted and should configure privacy controls accordingly.
