Giter VIP home page Giter VIP logo

jaeger-client-php's Introduction

Build Status PHP version

Jaeger Bindings for PHP OpenTracing API

This is a client-side library that can be used to instrument PHP apps for distributed trace collection, and to send those traces to Jaeger. See the OpenTracing PHP API for additional detail.

Contributing and Developing

Please see CONTRIBUTING.md.

Installation

Jaeger client can be installed via Composer:

composer require jonahgeorge/jaeger-client-php

Getting Started

<?php

require_once 'vendor/autoload.php';

use Jaeger\Config;
use OpenTracing\GlobalTracer;

$config = new Config(
    [
        'sampler' => [
            'type' => Jaeger\SAMPLER_TYPE_CONST,
            'param' => true,
        ],
        'logging' => true,
    ],
    'your-app-name'
);
$config->initializeTracer();

$tracer = GlobalTracer::get();

$scope = $tracer->startActiveSpan('TestSpan', []);
$scope->close();

$tracer->flush();

Samplers

List of supported samplers, for more info about samplers, please read Jaeger Sampling guide.

Const sampler

This sampler either samples everything, or nothing.

Configuration
'sampler' => [
    'type' => Jaeger\SAMPLER_TYPE_CONST,
    'param' => true, // boolean wheter to trace or not
],

Probabilistic sampler

This sampler samples request by given rate.

Configuration
'sampler' => [
    'type' => Jaeger\SAMPLER_TYPE_PROBABILISTIC,
    'param' => 0.5, // float [0.0, 1.0]
],

Rate limiting sampler

Samples maximum specified number of traces (requests) per second.

Requirements
  • psr/cache PSR-6 cache component to store and retrieve sampler state between requests. Cache component is passed to Jaeger\Config trough its constructor.
  • hrtime() function, that can retrieve time in nanoseconds. You need either php 7.3 or PECL/hrtime extension.
Configuration
'sampler' => [
    'type' => Jaeger\SAMPLER_TYPE_RATE_LIMITING,
    'param' => 100 // integer maximum number of traces per second,
    'cache' => [
        'currentBalanceKey' => 'rate.currentBalance' // string
        'lastTickKey' => 'rate.lastTick' // string
    ]
],

Dispatch mode

The library supports 3 ways of sending data to Jaeger Agent:

  1. Zipkin.thrift over Compact protocol (socket - UDP) - default
  2. Jaeger.thrift over Binary protocol (socket - UDP)
  3. Jaeger.thrift over Binary protocol (HTTP)

If you want to enable "Jaeger.thrift over Binary protocol" one or other, than you need to set dispatch_mode config option or JAEGER_DISPATCH_MODE env variable.

Allowed values for dispatch_mode are:

  • jaeger_over_binary_udp
  • jaeger_over_binary_http
  • zipkin_over_compact_udp

There are 3 constants available, so it is better to use them:

class Config
{
    const ZIPKIN_OVER_COMPACT_UDP   = "zipkin_over_compact_udp";
    const JAEGER_OVER_BINARY_UDP    = "jaeger_over_binary_udp";
    const JAEGER_OVER_BINARY_HTTP   = "jaeger_over_binary_http";
    ...
}

A possible config with custom dispatch_mode can look like this:

// config.php

use Jaeger\Config;

return [
    'sampler' => [
        'type' => Jaeger\SAMPLER_TYPE_CONST,
        'param' => true,
    ],
    'logging' => true,
    "tags" => [
        // process. prefix works only with JAEGER_OVER_HTTP, JAEGER_OVER_BINARY
        // otherwise it will be shown as simple global tag
        "process.process-tag-key-1" => "process-value-1", // all tags with `process.` prefix goes to process section
        "process.process-tag-key-2" => "process-value-2", // all tags with `process.` prefix goes to process section
        "global-tag-key-1" => "global-tag-value-1", // this tag will be appended to all spans
        "global-tag-key-2" => "global-tag-value-2", // this tag will be appended to all spans
    ],
    "local_agent" => [
        "reporting_host" => "localhost", 
//        You can override port by setting local_agent.reporting_port value   
        "reporting_port" => 6832
    ],
//     Different ways to send data to Jaeger. Config::ZIPKIN_OVER_COMPACT - default):
    'dispatch_mode' => Config::JAEGER_OVER_BINARY_UDP,
];

The full example you can see at examples directory.

By default, for each dispatch_mode there is default reporting_port config value. Table with default values you can see below:

dispatch_mode default reporting_port
ZIPKIN_OVER_COMPACT_UDP 5775
JAEGER_OVER_BINARY_UDP 6832
JAEGER_OVER_BINARY_HTTP 14268

IPv6

In case you need IPv6 support you need to set ip_version Config variable. By default, IPv4 is used. There is an alias Config::IP_VERSION which you can use as an alternative to raw ip_version.

Example:

use Jaeger\Config;

$config = new Config(
    [
        "ip_version" => Config::IPV6, // <-- or use Config::IP_VERSION constant
        'logging' => true,
        'dispatch_mode' => Config::JAEGER_OVER_BINARY_UDP,
    ],
    'serviceNameExample',
);
$config->initializeTracer();

or

use Jaeger\Config;

$config = new Config(
    [
        Config::IP_VERSION => Config::IPV6, // <--
        'logging' => true,
        'dispatch_mode' => Config::JAEGER_OVER_BINARY_UDP,
    ],
    'serviceNameExample',
);
$config->initializeTracer();

Testing

Tests are located in the tests directory. See tests/README.md.

Roadmap

License

MIT License.

jaeger-client-php's People

Contributors

alexeyshockov avatar asyazwan avatar avrphp avatar blong14 avatar dafresh avatar dkemper1 avatar egor-muindor avatar enleur avatar filipbenco avatar fredipevcin avatar goresakuraba avatar heh9 avatar idr0id avatar jans-jeroen avatar jaredru avatar jonahgeorge avatar limingxinleo avatar m1x0n avatar masterada avatar mszabo-wikia avatar nauxliu avatar pekhota avatar peter279k avatar piotrooo avatar podtserkovskiy avatar rostyslavkhaniukov avatar sergeyklay avatar sfunkhouser avatar taarim avatar tommyseus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jaeger-client-php's Issues

Booleans in tags are casted to string

Hi,

When i add a tag named error and set its value to true it is casted to 1.
If Jaeger UI get a span with tag error with true boolean value it has an exclamation mark next to it.
It helps to fast locate an error in application.
The problem occures after last commit - Jaeger Thrift over Binary protocol implementation (UDP 6832 & Http 14โ€ฆ
I tried to send spans over UDP port 6832 and TCP port 14268, in both cases it cast boolean to string.

I made some code changes localy in files:
\Jaeger\Span
`
...
const SPECIAL_TAGS = [
PEER_SERVICE => 'setPeerService',
PEER_HOST_IPV4 => 'setPeerHostIpv4',
PEER_PORT => 'setPeerPort',
SPAN_KIND => 'setSpanKind',
COMPONENT => 'setComponent',
'error' => 'setError',
];

private function setError($value): bool
{
    $this->tags['error'] = new BinaryAnnotation([
        'key' => 'error',
        'value' => $value,
        'annotation_type' => AnnotationType::BOOL,
    ]);

    return true;
}

...
\Jaeger\Mapper\SpanToJaegerMapper
...
public function mapSpanToJaeger(Span $span) : JaegerThriftSpan
{
$timestamp = $span->getStartTime();
$duration = $span->getEndTime() - $span->getStartTime();

    /** @var Tag[] $tags */
    $tags = [];

    $tags[] = new Tag([
        "key" => COMPONENT,
        "vType" => TagType::STRING,
        "vStr" => $span->getComponent() ?? $span->getTracer()->getServiceName(),
    ]);

    /** @var BinaryAnnotation[] $binaryAnnotationTags */
    $binaryAnnotationTags = $span->getTags();
    foreach ($binaryAnnotationTags as $binaryAnnotationTag) {
        if (in_array($binaryAnnotationTag->key, $this->specialSpanTags, true)) {
            continue ;
        }

        if (strpos($binaryAnnotationTag->key, $this->processTagsPrefix) === 0) {
            continue;
        }

        if ($binaryAnnotationTag->key === 'error') {
            $tags[] = new Tag([
                "key" => $binaryAnnotationTag->key,
                "vType" => TagType::BOOL,
                "vBool" => $binaryAnnotationTag->value,
            ]);

            continue;
        }

        $tags[] = new Tag([
            "key" => $binaryAnnotationTag->key,
            "vType" => TagType::STRING,
            "vStr" => $binaryAnnotationTag->value,

        ]);
    }

    /** @var Log[] $logs */
    $logs = [];

    $spanLogs = $span->getLogs();

    foreach ($spanLogs as $spanLog) {
        /** @var Tag $fields */
        $fields = [];

        if (!empty($spanLog["fields"])) {
            $fields[] = new Tag([
                "key" => "event",
                "vType" => TagType::STRING,
                "vStr" => json_encode($spanLog["fields"])
            ]);
        }

        $logs[] = new Log([
            "timestamp" => $spanLog["timestamp"],
            "fields" => $fields
        ]);
    }

    return new JaegerThriftSpan([
        "traceIdLow" => (int)$span->getContext()->getTraceId(),
        "traceIdHigh" => 0,
        "spanId" => (int)$span->getContext()->getSpanId(),
        "parentSpanId" => (int)$span->getContext()->getParentId(),
        "operationName" => $span->getOperationName(),
        "startTime" => $timestamp,
        "duration" => $duration,
        "flags" => (int)$span->isDebug(),
        "tags" => $tags,
        "logs" => $logs
    ]);
}

...
`
After this changes error tag is sending boolean and it is marked in UI as error with exclamation mark.
Is there any chance to implement casting error tag to bool?

Unsupported operand types when using `addBaggageItem()`

Using $scope->getSpan()->addBaggageItem($k, $v); will throw an exception of Unsupported operand types due to baggage not guaranteed to be an array and thus failing when non-arrays are passed to SpanContext::withBaggageItem().

In my case, Tracer::startSpan() will initialize baggage to null for parent-less spans. So later on merge of arrays in SpanContext::withBaggageItem() will be: [$key => $value] + null.

I think we should ensure SpanContext::$baggage to always be an array.

Allowed memory size error

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 65011720 bytes) in E:\workspace\php\BastetYii\vendor\packaged\thrift\src\Thrift\Protocol\TCompactProtocol.php on line 123

I'm working on win10.
this issue only report on windows, Linux don't have it.

Pass by reference?

Should $carrier be passed by reference here?

public function inject(SpanContext $spanContext, $carrier)

Please excuse my lack of PHP knowledge as I am still learning the language. I'm calling Inject on the tracer to fill in a carrier with the span context information.

$carrier = [];

$this->getGlobalTracer()->inject(
      $span->getContext(),
      TEXT_MAP,
      $carrier
 );

return $carrier;

Curly braces deprecated in php 7.4 in Thrift package

Hi,

I have got an error on php 7.4
Array and string offset access syntax with curly braces is deprecated in /var/www/vendor/packaged/thrift/src/Thrift/Transport/THttpClient.php
on line 100

There is a fix in thrift package in version 0.14.1
apache/thrift@44b0b5d

Is there any chance that can you upgrade version of Thrift to 0.14.1?

Don't work

Composer.json
"jonahgeorge/jaeger-client-php": "*"

Within controller
`$config = new Config(
[
'sampler' => [
'type' => 'const',
'param' => true,
],
'logging' => true,
],
'test'
);
$config->initializeTracer();

    $tracer = GlobalTracer::get();

    $scope = $tracer->startSpan('TestSpan');
    $scope->finish();

    $tracer->flush();`

But when I go to http://localhost:16686/search
I don't see service 'test'

How to create multiple tracers?

The example in the Readme only shows how to create/initialize the GlobalTracer. How to create another (local) tracer (e.g. for SQL spans)?

At least, I'd like to get spans in jaeger shown in a different color if they do not belong to my backend, but to the database. See screenshot from Jaeger documentation:

Are multiple tracers the wrong approach for this?

ThriftUdpTransport is locked onto IPv4

$this->socket = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); line locks implementation to IPv4 without any options. It makes package unusable because my company is on IPv6 almost entierly. Supporting IPv4 without any options looks a bit dated to me.

Options I see:

  • Autodetect scheme. If $host is IP address, you can tell if this is IPv4 or IPv6. If not - you can query DNS and then detect.
  • Allow options to be passed to a ThriftUdpTransport to specify IP protocol version.

Span tags are not unique

$span->setTag('component', 'api'); // inherited from tracer
$span->setTag('component', 'database');

var_dump($span->getTags());
{
  [0]=>
  object(Jaeger\ThriftGen\BinaryAnnotation)#27 (4) {
    ["key"]=>
    string(9) "component"
    ["value"]=>
    string(5) "api"
    ["annotation_type"]=>
    int(6)
    ["host"]=>
    NULL
  }
  [1]=>
  object(Jaeger\ThriftGen\BinaryAnnotation)#28 (4) {
    ["key"]=>
    string(9) "component"
    ["value"]=>
    string(5) "database"
    ["annotation_type"]=>
    int(6)
    ["host"]=>
    NULL
  }
}

PHP 8.1 throws warning with package

Running this package on PHP 8.1, returns a php notice

Deprecated: Return type of Jaeger\SpanContext::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/html/vendor/jonahgeorge/jaeger-client-php/src/Jaeger/SpanContext.php on line 48

PHP 8 support

Hi, are you planning on making it compatible with php8?

If this is not within your timeframe, would you be open for a pr?

tag values are limited to 1024 chars

Tag values of type string are limited to 1024 characters (see src/Jaeger/Span.php). No error or warning is logged, when this happens, which would be helpful.

Is there a specific reason for this hard limit? The Go client made it configurable. Is this possible in the PHP client, too?


My use case is tracing SQL queries. A recommended best practice is to add the query string as db.statement. Many of them have ca. 1200 characters and some have ca. 4000-6000 characters.

Allow probabilistic sampler with rate 0 and 1

        if ($rate <= 0.0 || $rate >= 1.0) {
            throw new OutOfBoundsException('Sampling rate must be between 0.0 and 1.0.');
        }

should be

        if ($rate < 0.0 || $rate > 1.0) {
            throw new OutOfBoundsException('Sampling rate must be between 0.0 and 1.0.');
        }

It would be easier to configure development sampler (can use the same sampler type with 1.0 rate), it would be easier to implement adaptive sampler and it's consitent with go client (didn't check other clients): https://github.com/jaegertracing/jaeger-client-go/blob/master/sampler.go#L111

semm not work for jaeger version 1.34.1

code to run jaeger

export SPAN_STORAGE_TYPE=memory
./jaeger-collector 
./jaeger-query
./jaeger-agent  --reporter.grpc.host-port=127.0.0.1:14250

run php like example

$config = new Config(
    [
        'sampler' => [
            'type' => Jaeger\SAMPLER_TYPE_CONST,
            'param' => true,
        ],
        'logging' => true,
        "tags" => [
            // process. prefix works only with JAEGER_OVER_HTTP, JAEGER_OVER_BINARY
            // otherwise it will be shown as simple global tag
            "process.process-tag-key-1" => "process-value-1", // all tags with `process.` prefix goes to process section
            "process.process-tag-key-2" => "process-value-2", // all tags with `process.` prefix goes to process section
            "global-tag-key-1" => "global-tag-value-1", // this tag will be appended to all spans
            "global-tag-key-2" => "global-tag-value-2", // this tag will be appended to all spans
        ],
        "local_agent" => [
            "reporting_host" => "localhost",
            //You can override port by setting local_agent.reporting_port value
            "reporting_port" => 6832
        ],
        // Different ways to send data to Jaeger. Config::ZIPKIN_OVER_COMPACT - default):
        'dispatch_mode' => Config::JAEGER_OVER_BINARY_UDP,
    ],
    'your-app-name'
);
$config->initializeTracer();
$tracer = GlobalTracer::get();
......

I can't get any info from jaeger-agent or Ui
if "reporting_port" => 6831 there is an error on jaeger-agent log

{"level":"error","ts":1653836163.4486067,"caller":"processors/thrift_processor.go:123","msg":"Processor failed","error":"Expected protocol id 82 but got 80","stacktrace":"github.com/jaegertracing/jaeger/cmd/agent/app/processors.(*ThriftProcessor).processBuffer\n\tgithub.com/jaegertracing/jaeger/cmd/agent/app/processors/thrift_processor.go:123\ngithub.com/jaegertracing/jaeger/cmd/agent/app/processors.NewThriftProcessor.func2\n\tgithub.com/jaegertracing/jaeger/cmd/agent/app/processors/thrift_processor.go:87"}

so i think link is success,but why when "reporting_port" => 6832 there no info log

I'm not sure where is wrong , any suggestion ? please.

Multi-span traces not being reported

Reproduction:

Many spans:

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use Jaeger\Config;
use OpenTracing\GlobalTracer;

$config = new Config(
    [
        'sampler' => ['type' => 'const', 'param' => true],
        'logging' => true,
    ],
    'stress-many'
);
$tracer = $config->initializeTracer();

$rootSpan = $tracer->startSpan('ParentSpan', []);

foreach (range(0, 100) as $index) {
  $childSpan = $tracer->startSpan("ChildSpan$index", ['child_of' => $rootSpan]);
  $childSpan->finish();
}

$rootSpan->finish();
$tracer->flush();

Deeply-nested spans:

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use Jaeger\Config;
use OpenTracing\GlobalTracer;

$config = new Config(
    [
        'sampler' => ['type' => 'const', 'param' => true],
        'logging' => true,
    ],
    'stress-nested'
);
$tracer = $config->initializeTracer();

$rootSpan = $tracer->startSpan('ParentSpan', []);

$parentSpan = $rootSpan;
foreach (range(0, 100) as $index) {
  $childSpan = $tracer->startSpan("ChildSpan$index", ['child_of' => $parentSpan]);
  $childSpan->finish();
  $parentSpan = $childSpan;
}

$rootSpan->finish();
$tracer->flush();

addZipkinAnnotations should fallback to endpoint if peer is not set

In case a trace is set to rpc client or rpc server, but no peer tag is set, the service name will be empty.

instead of

        if ($span->isRpc()) {
            $isClient = $span->isRpcClient();

            if ($span->peer) {
                $host = $this->makeEndpoint(
                    $span->peer['ipv4'] ?? 0,
                    $span->peer['port'] ?? 0,
                    $span->peer['service_name'] ?? ''
                );

                $key = ($isClient) ? self::SERVER_ADDR : self::CLIENT_ADDR;

                $peer = $this->makePeerAddressTag($key, $host);
                $span->tags[$key] = $peer;
            }
        } else {
            $tag = $this->makeLocalComponentTag(
                $span->getComponent() ?? $span->getTracer()->getServiceName(),
                $endpoint
            );

            $span->tags[COMPONENT] = $tag;
        }

do


        if ($span->isRpc() && $span->peer) {
            $isClient = $span->isRpcClient();

            $host = $this->makeEndpoint(
                $span->peer['ipv4'] ?? 0,
                $span->peer['port'] ?? 0,
                $span->peer['service_name'] ?? ''
            );

            $key = ($isClient) ? self::SERVER_ADDR : self::CLIENT_ADDR;

            $peer = $this->makePeerAddressTag($key, $host);
            $span->tags[$key] = $peer;
        } else {
            $tag = $this->makeLocalComponentTag(
                $span->getComponent() ?? $span->getTracer()->getServiceName(),
                $endpoint
            );

            $span->tags[COMPONENT] = $tag;
        }

DGRAM buffer limit and ignoring socket_send warnings

Hi,
I'm working on integration your client with my symfony project.
I found a questionable decision, look at ThriftUdpTransport.php:99 (https://github.com/jonahgeorge/jaeger-client-php/blob/master/src/Jaeger/ThriftUdpTransport.php).
Why have you decided to ignore warnings?
The client has a buffer limit which is equal 64000 bytes, but MacOS has 9216 bytes limit by default (at least on MacOS Hight Sierra), the command to check sysctl net.inet.udp.maxdgram.
When I flushed a trace with thousands of spans I was getting nothing, no errors, no a trace on Jaeger, nothing.
It took much time before I found that MacOS has 9216 bytes limit for udp dgram...

How to ensure closing?

If you have multiple operations that should be wrapped by spans. How do you ensure that the span/scope is closed, even if an exception is thrown by one of the operations?

Example:

$tracer = GlobalTracer::get();
register_shutdown_function(function () {
  GlobalTracer::get()->flush();
});

try {
  $scope = $tracer->startActiveSpan('doA', []);
  doA();
  $scope->close();
  $scope = $tracer->startActiveSpan('doB', []);
  doB();
} finally {
  // may be unset if `$tracer->startActiveSpan` throws an exception
  if (isset($scope)) {
    $scope->close();
  }
}

IMO this is quite verbose. Besides, what if $scope->close(); throws an exception?

What (e.g. pattern) do you recommend?

Is there a maximum of sub-spans?

Is there a (intended) maximum of sub-spans? I'm creating a larger trace of a request with several SQL statements (a span for each). It works up to a total of 59 spans (depth 4), where one span has 50 sub-spans (children). If I add more than 50 sub-spans, the trace is not found in Jaeger UI and the log of jaegertracing/all-in-one:1.26 shows two errors

{
  "level": "error",
  "ts": 1632257043.8104687,
  "caller": "processors/thrift_processor.go:123",
  "msg": "Processor failed",
  "error": "*jaeger.Batch error reading struct: *jaeger.Span error reading struct: *jaeger.Tag error reading struct: *jaeger.Tag field 0 read error: EOF",
  "stacktrace": "github.com/jaegertracing/jaeger/cmd/agent/app/processors.(*ThriftProcessor).processBuffer\n\tgithub.com/jaegertracing/jaeger/cmd/agent/app/processors/thrift_processor.go:123\ngithub.com/jaegertracing/jaeger/cmd/agent/app/processors.NewThriftProcessor.func2\n\tgithub.com/jaegertracing/jaeger/cmd/agent/app/processors/thrift_processor.go:87"
}
{
  "level": "error",
  "ts": 1632257043.824714,
  "caller": "processors/thrift_processor.go:123",
  "msg": "Processor failed",
  "error": "EOF",
  "stacktrace": "github.com/jaegertracing/jaeger/cmd/agent/app/processors.(*ThriftProcessor).processBuffer\n\tgithub.com/jaegertracing/jaeger/cmd/agent/app/processors/thrift_processor.go:123\ngithub.com/jaegertracing/jaeger/cmd/agent/app/processors.NewThriftProcessor.func2\n\tgithub.com/jaegertracing/jaeger/cmd/agent/app/processors/thrift_processor.go:87"
}

jonahgeorge/jaeger-client-php version 1.2.4. My configuration:

$config = new \Jaeger\Config(
  [
    'sampler' => [
      'type' => \Jaeger\SAMPLER_TYPE_CONST,
      'param' => true,
    ],
    'logging' => true,
    "tags" => [
      "foo" => "bar",
    ],
    "local_agent" => [
      "reporting_host" => "jaeger",
    ],
    'dispatch_mode' => \Jaeger\Config::JAEGER_OVER_BINARY_UDP,
  ],
  'my-app',
);

Add psr/cache 2.0 support

Using this package with symfony we cant update framework to 6.* version.

required cache/array-adapter library already supports cache 2.0 version

cache/adapter-common      1.3.0  requires  psr/cache (^1.0 || ^2.0)  
cache/array-adapter       1.2.0  requires  psr/cache (^1.0 || ^2.0)  
cache/hierarchical-cache  1.2.0  requires  psr/cache (^1.0 || ^2.0)  
cache/tag-interop         1.1.0  requires  psr/cache (^1.0 || ^2.0)

Allowed memory size of bytes exhausted

Allowed memory size of 419430400 bytes exhausted (tried to allocate 65536 bytes) in jaeger-client-php/src/Jaeger/Thrift/Agent/Agent_emitBatch_args.php on line 51

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.