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.

Note

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

ChooseWhen it is the better first moveWhat you get
Coding agent or wizardYou want instrumentation without writing it yourselfNew runs sent as your application executes
SDK by hand (this page)You want to control every line of instrumentationNew runs sent as your application executes
ImportYou have a failure to investigate nowExisting traces copied into a Neatlogs project
BothYou want history and continuous coverageImported 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.

Note

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.

Note

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.

Warning

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

SymptomCheck first
Nothing arrivesSDK Doctor, project key, region endpoint, active project, time range, and exporter flush
Several roots appear for one requestTrace context propagation across processes and workers
LLM or tool steps are missingWhether the framework integration covers that library and code path
Run appears in the wrong projectThe key used by the application, or the project selected when an import started
Process exits before sendingFlush or shutdown behavior for short-lived scripts
Sensitive content is visibleSDK 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.

Next step

Use that run to investigate a real failure →

On this page

Ask Neatlogs AI

Answers from the docs

How can I help?

Ask anything about instrumenting, tracing, or the Neatlogs dashboard.