NAME

    OpenTelemetry::Instrumentation::Mango - OpenTelemetry instrumentation
    for Mango

SYNOPSIS

      use OpenTelemetry::Instrumentation 'Mango';
    
      my $mango = Mango->new('mongodb://localhost:27017');
      $mango->db('test')->collection('foo')->insert({ bar => 'baz' });
      # ... a client span is created for the operation

DESCRIPTION

    OpenTelemetry::Instrumentation::Mango adds OpenTelemetry tracing to the
    Mango MongoDB driver. It follows the same model as
    OpenTelemetry::Instrumentation::DBI: installing this instrumentation
    wraps selected methods so that every MongoDB operation runs inside a
    CLIENT span.

    Yes, Mango uses an obsolete wire protocol, and yes, it has not been
    updated since 2014, but it still works with older versions of MongoDB
    and this module will emit telemetry for this stack if you need it.

    The instrumentation wraps the semantic funnels of Mango, which means
    every wire operation is covered:

      * "command" in Mango::Database: every database command (which
      includes all collection CRUD operations, as they are implemented as
      commands: insert, update, delete, findAndModify, count, distinct,
      aggregate, and friends).

      * Mango::Cursor::Query _start: the initial find query.

      * "get_more" in Mango and "kill_cursors" in Mango: cursor pagination
      and cleanup.

 Spans

    Each operation produces a span named "<operation> <db.collection>" (for
    example insert test.foo), or "<operation> <db>" for database-level
    commands without a collection target. The name is truncated to 100
    characters. Because "kill_cursors" in Mango receives a cursor id rather
    than a namespace, the id is kept in the span name instead of any
    database attributes.

 Attributes

    Spans generated by this instrumentation will record the following
    attributes:

    db.system.name

      Always mongodb.

    db.name

      Name of the database the operation ran against.

    db.collection.name

      Name of the targeted collection, when the operation targets one.

    db.operation.name

      The operation: the command name for database commands (insert, count,
      findAndModify, ...), or find, get_more, kill_cursors.

    db.statement

      The command or query document encoded as JSON, truncated to 512
      characters. Omitted if it cannot be encoded.

    server.address and server.port

      Taken from the first entry of $mango->hosts, with a default value of
      27017.

 Blocking and non-blocking operations

    Both blocking and non-blocking (callback-style) operations are
    supported. For blocking operations, the span is ended once the call
    returns (or dies, in which case the exception is recorded and the span
    status is set to error). For non-blocking operations, the span is ended
    when Mango invokes the callback: the status is set to error if Mango
    passed an error as the first callback argument after the invokant, and
    to success otherwise. The callback runs with the captured context
    restored, so spans created inside it nest under the operation span.
    Please not that if Mango never invokes the callback, the span for the
    non-blocking operation will not be ended.

    This instrumentation never starts or stops any event loop, so it is
    safe to use under Mojolicious applications: blocking operations
    continue to use the Mango object's own ioloop, and non-blocking
    operations continue to be driven by whatever loop is running the
    application.

 Testing with Test::Mock::Mango

    If Test::Mock::Mango is loaded before this instrumentation is
    installed, the same wrappers are installed on the mocked classes
    (Test::Mock::Mango::DB, Test::Mock::Mango::Collection, and
    Test::Mock::Mango::Cursor), which lets you test instrumented code
    without a MongoDB server. In production, Test::Mock::Mango is not
    loaded, so this has no effect. Note that mocked cursors carry no
    collection reference, so spans produced through them only carry the
    operation name. Additionally, spans produced through mocked collection
    methods do not carry a db.statement attribute.

 Running the integration tests

    The test suite is fully offline by default:
    t/OpenTelemetry/Instrumentation/Mango.t runs against Test::Mock::Mango
    stubs and never opens a network connection. Additionally, t/online.t
    runs the same instrumentation against a real MongoDB server, but only
    when the TEST_ONLINE environment variable holds a connection string;
    without it, that test skips.

    Note that as mentioned above Mango speaks MongoDB's legacy wire
    protocol, which was deprecated in MongoDB 5.0 and removed in MongoDB
    5.1, so use a server of version 5.0 or earlier. For example, with
    Docker:

      docker run --rm -d --name otel-mango-test \
        -p 127.0.0.1:28017:27017 mongo:4.4
    
      TEST_ONLINE=mongodb://127.0.0.1:28017 prove -lv t/online.t
    
      docker stop otel-mango-test

    The test uses its own database (otel_mango_online_test) and drops it
    when it finishes, and the container above is removed as soon as it
    stops, so no data is left behind.

TODO

    Add examples

    Add option to redact statement attribute

SEE ALSO

    OpenTelemetry

    OpenTelemetry::Instrumentation

    OpenTelemetry::Instrumentation::DBI.

    Mango,

    Test::Mock::Mango.

AUTHORS

    Javier Arturo Rodriguez <javier@cpan.org>

    A significant part of this code has been shamelessly ripped off
    OpenTelemetry::Instrumentation::DBI written by José Joaquín Atria.

COPYRIGHT

    This software is copyright (c) 2026 by Javier Arturo Rodriguez.

LICENSE

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

