Skip to content

Comments

Opentelemetry init#29

Open
AjmalPonneth wants to merge 12 commits intosaleor:mainfrom
AjmalPonneth:opentelemetry-init
Open

Opentelemetry init#29
AjmalPonneth wants to merge 12 commits intosaleor:mainfrom
AjmalPonneth:opentelemetry-init

Conversation

@AjmalPonneth
Copy link

Resolves #24

@maarcingebala
Copy link
Member

@AjmalPonneth Big thanks for the contribution. I've added some comments to look into.

@AjmalPonneth
Copy link
Author

@maarcingebala will be addressing the comments you raised ASAP.

@AjmalPonneth
Copy link
Author

@maarcingebala, can you please check now

@maarcingebala
Copy link
Member

@AjmalPonneth Thanks for making changes. What about the GraphQL calls observability? Was it removed?

@AjmalPonneth
Copy link
Author

@maarcingebala Yes, it was removed from async_base_client.py since that file is generated by codegen. Could you please advise where is the appropriate place would be to instrument the GraphQL calls?

@maarcingebala
Copy link
Member

I think for now we could focus on tracing and have three types of calls:

  • tool calls (like orders tool, products, etc.)
  • Saleor GraphQL API calls - since this client is generated, maybe we could create another module called graphql_client.py that would provide a wrapper for the generated client, that would extend the original calls with tracing (by some wrapping with decorators or something similar)
  • We could check if we can add tracing for built-in MCP methods, such as tools/list - but this could be added later.

@maarcingebala
Copy link
Member

BTW, I think at some point OpenTelemetry support will be added to FastMCP or MCP spec, so hopefully it will be supported out of the box. Some links to have a look into:

@AjmalPonneth
Copy link
Author

Noted.

@AjmalPonneth
Copy link
Author

AjmalPonneth commented Nov 18, 2025

@maarcingebala, regarding the tracing for GraphQL calls, can we structure it like this in our proposed graphql_client.py

def instrument_graphql_client(client: AsyncBaseClient) -> AsyncBaseClient:
    original_json = client._execute_json

    async def traced_json(query, operation_name, variables, **kwargs):
        headers = {"Content-Type": "application/json"}
        headers.update(kwargs.get("headers", {}))
        inject(headers)
        merged_kwargs = {**kwargs, "headers": headers}
        span_name = f"saleor.graphql.{operation_name or 'query'}"
        with start_as_current_span(
            span_name,
            kind=SpanKind.CLIENT,
            attributes={
                mcp_attr.HTTP_METHOD: "POST",
                mcp_attr.URL_FULL: client.url,
                mcp_attr.GRAPHQL_OPERATION_NAME: operation_name,
                mcp_attr.GRAPHQL_VARIABLES: str(variables),
                mcp_attr.SALEOR_ENDPOINT: client.url,
            },
        ) as span:
            response = await original_json(
                query=query,
                operation_name=operation_name,
                variables=variables,
                **merged_kwargs,
            )
            span.set_attribute(mcp_attr.HTTP_STATUS_CODE, response.status_code)
            return response

    client._execute_json = traced_json
    return client


client = AsyncBaseClient(url=saleor_url)
GraphQLClient = instrument_graphql_client(client)

This would give us a traced GraphQLClient instance, which we could then use inside our higher-level Client(GraphQLClient) wrapper.

@maarcingebala
Copy link
Member

@AjmalPonneth Yes I think this is an approach that we could try to built here, I was thinking about something like what you described.

@AjmalPonneth
Copy link
Author

@maarcingebala, I've added observability for GraphQL calls. Kindly check and advise.

@przlada przlada removed their request for review February 9, 2026 09:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add OpenTelemetry integration

2 participants