Skip to content

Commit

Permalink
Add option for simpler GraphQL resource names
Browse files Browse the repository at this point in the history
The current ddtrace GraphQL integration sets the full query as the resource name. This is fragile for monitoring and metrics purposes because a simple field change will result in a completely new name. In addition, it's kind of unsightly to see a resource name that's so long.

As an example, take a look at ddtrace-graphql. Normally, I'd just use that, but it's out of date and incompatible with the latest versions of ddtrace as well as graphql.

Addresses DataDog#10875
  • Loading branch information
goodspark committed Oct 1, 2024
1 parent 0a6b056 commit f349dab
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
10 changes: 10 additions & 0 deletions ddtrace/contrib/graphql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@
Enabling instrumentation for resolvers will produce a ``graphql.resolve`` span for every graphql field.
For complex graphql queries this could produce large traces.
.. py:data:: ddtrace.config.graphql["simplify_resources"]
To enable this option, set ``DD_TRACE_GRAPHQL_SIMPLIFY_RESOURCES`` to True.
Default: ``False``
When True, resource names on GraphQL spans will be reduced to just the query or mutation name, if provided. Otherwise
the entire query will be used.
To configure the graphql integration using the
``Pin`` API::
Expand All @@ -44,6 +53,7 @@
Pin.override(graphql, service="mygraphql")
"""

from ddtrace.internal.utils.importlib import require_modules


Expand Down
15 changes: 14 additions & 1 deletion ddtrace/contrib/internal/graphql/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def get_version():
dict(
_default_service=schematize_service_name("graphql"),
resolvers_enabled=asbool(os.getenv("DD_TRACE_GRAPHQL_RESOLVERS_ENABLED", default=False)),
simplify_resource=asbool(os.getenv("DD_TRACE_GRAPHQL_SIMPLIFY_RESOURCES", default=False)),
),
)

Expand Down Expand Up @@ -168,10 +169,22 @@ def _traced_execute(func, args, kwargs):
else:
document = get_argument_value(args, kwargs, 1, "document")
source_str = _get_source_str(document)
resource = source_str
if config.graphql.simplify_resource:
# queries can look like:
# query Name(args) {...
# query Name {...
# query {...
# simplified names only make sense for the first two. the last one should just default to the full query
# split on either the query body brace or the arg parens
resource = re.split("[({]", resource, maxsplit=1)[0]
resource = resource.strip()
if resource in ("query", "mutation"):
resource = source_str

with pin.tracer.trace(
name="graphql.execute",
resource=source_str,
resource=resource,
service=trace_utils.int_service(pin, config.graphql),
span_type=SpanTypes.GRAPHQL,
) as span:
Expand Down

0 comments on commit f349dab

Please sign in to comment.