Skip to content

Commit

Permalink
refactor sdk/api logging (open-telemetry#1105)
Browse files Browse the repository at this point in the history
send errors/warnings/etc by default through PHP's error_log. This gives more control to administrators, since error_log can
be configured to write to any stream (file, stderr, etc). I think it's also less surprising for people trying out otel (particularly
with development PHP settings, where trigger_error often breaks an application).
Adding a configuration value to control where logs go: OTEL_PHP_LOG_DESTINATION.
  • Loading branch information
brettmc authored Aug 30, 2023
1 parent 197a7a4 commit 73ff5ad
Show file tree
Hide file tree
Showing 41 changed files with 514 additions and 253 deletions.
40 changes: 40 additions & 0 deletions examples/global_providers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

use OpenTelemetry\API\Globals;
use OpenTelemetry\API\Instrumentation\Configurator;
use OpenTelemetry\SDK\Trace\SpanExporter\ConsoleSpanExporterFactory;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;

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

/**
* Example of globally registering <Signal>Provider instances.
* Generally this is hidden inside the SDK builder or SDK autoloading,
* but you can also do it manually. The providers are stored in
* context, and reset to previous values or defaults when the
* scope is detached.
*/

//before, a no-op provider is provided by default
echo 'Before: ' . get_class(Globals::tracerProvider()) . PHP_EOL;

$tracerProvider = TracerProvider::builder()->addSpanProcessor(
new SimpleSpanProcessor(
(new ConsoleSpanExporterFactory())->create()
)
)->build();

$configurator = Configurator::create()
->withTracerProvider($tracerProvider);

$scope = $configurator->activate();
//activated, now our $tracerProvider is globally available
echo 'During: ' . get_class(Globals::tracerProvider()) . PHP_EOL;

$scope->detach();

//after scope detached, back to default no-op providers:
echo 'After: ' . get_class(Globals::tracerProvider()) . PHP_EOL;
8 changes: 0 additions & 8 deletions examples/logs/exporters/otlp_grpc.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

namespace OpenTelemetry\Example;

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Logs\EventLogger;
use OpenTelemetry\API\Logs\LogRecord;
use OpenTelemetry\API\Signals;
Expand All @@ -19,14 +16,9 @@
use OpenTelemetry\SDK\Logs\LoggerProvider;
use OpenTelemetry\SDK\Logs\LogRecordLimitsBuilder;
use OpenTelemetry\SDK\Logs\Processor\BatchLogRecordProcessor;
use Psr\Log\LogLevel;

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

LoggerHolder::set(
new Logger('otel-php', [new StreamHandler(STDOUT, LogLevel::DEBUG)])
);

$transport = (new GrpcTransportFactory())->create('http://collector:4317' . OtlpUtil::method(Signals::LOGS));
$exporter = new LogsExporter($transport);
$loggerProvider = new LoggerProvider(
Expand Down
8 changes: 0 additions & 8 deletions examples/logs/exporters/otlp_http.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

namespace OpenTelemetry\Example;

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Logs\EventLogger;
use OpenTelemetry\API\Logs\LogRecord;
use OpenTelemetry\Contrib\Otlp\LogsExporter;
Expand All @@ -16,14 +13,9 @@
use OpenTelemetry\SDK\Logs\LoggerProvider;
use OpenTelemetry\SDK\Logs\LogRecordLimitsBuilder;
use OpenTelemetry\SDK\Logs\Processor\SimpleLogRecordProcessor;
use Psr\Log\LogLevel;

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

LoggerHolder::set(
new Logger('otel-php', [new StreamHandler(STDOUT, LogLevel::DEBUG)])
);

$transport = (new OtlpHttpTransportFactory())->create('http://collector:4318/v1/logs', 'application/json');
$exporter = new LogsExporter($transport);

Expand Down
2 changes: 0 additions & 2 deletions examples/metrics/exporters/otlp_grpc.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
use OpenTelemetry\SDK\Common\Time\ClockFactory;
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader;

\OpenTelemetry\API\LoggerHolder::set(new \Monolog\Logger('grpc', [new \Monolog\Handler\StreamHandler('php://stderr')]));

$clock = ClockFactory::getDefault();

$reader = new ExportingReader(
Expand Down
5 changes: 0 additions & 5 deletions examples/sdk_builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

declare(strict_types=1);

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use OpenTelemetry\API\Instrumentation\CachedInstrumentation;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
use OpenTelemetry\Contrib\Otlp\MetricExporter;
use OpenTelemetry\SDK\Common\Export\Http\PsrTransportFactory;
Expand All @@ -25,8 +22,6 @@

echo 'Starting SDK builder example' . PHP_EOL;

LoggerHolder::set(new Logger('grpc', [new StreamHandler('php://stderr')]));

$resource = ResourceInfoFactory::defaultResource();
$spanExporter = new InMemoryExporter();
$logRecordExporter = new \OpenTelemetry\SDK\Logs\Exporter\InMemoryExporter();
Expand Down
5 changes: 0 additions & 5 deletions examples/traces/exporters/otlp_file.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@

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

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\Contrib\Otlp\ContentTypes;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransportFactory;
use OpenTelemetry\SDK\Common\Time\ClockFactory;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;

LoggerHolder::set(new Logger('otlp-example', [new StreamHandler('php://stderr')]));

$filename = sys_get_temp_dir() . '/traces.jsonl';
$file = fopen($filename, 'a');
$transport = (new StreamTransportFactory())->create($file, ContentTypes::NDJSON);
Expand Down
2 changes: 0 additions & 2 deletions examples/traces/exporters/otlp_grpc.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;

\OpenTelemetry\API\LoggerHolder::set(new \Monolog\Logger('grpc', [new \Monolog\Handler\StreamHandler('php://stderr')]));

$transport = (new GrpcTransportFactory())->create('http://collector:4317' . OtlpUtil::method(Signals::TRACE));
$exporter = new SpanExporter($transport);
echo 'Starting OTLP GRPC example';
Expand Down
2 changes: 0 additions & 2 deletions examples/traces/exporters/otlp_grpc_from_factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

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

\OpenTelemetry\API\LoggerHolder::set(new \Monolog\Logger('grpc', [new \Monolog\Handler\StreamHandler('php://stderr')]));

/**
* Create an otlp+grpc tracer provider from TracerProviderFactory, using environment variables as input
*/
Expand Down
5 changes: 0 additions & 5 deletions examples/traces/exporters/otlp_http.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,11 @@

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

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;

LoggerHolder::set(new Logger('otlp-example', [new StreamHandler('php://stderr')]));

$transport = (new OtlpHttpTransportFactory())->create('http://collector:4318/v1/traces', 'application/x-protobuf');
$exporter = new SpanExporter($transport);

Expand Down
2 changes: 0 additions & 2 deletions examples/traces/exporters/otlp_http_from_factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

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

\OpenTelemetry\API\LoggerHolder::set(new \Monolog\Logger('grpc', [new \Monolog\Handler\StreamHandler('php://stderr')]));

/**
* Create an otlp+http/protobuf tracer provider from TracerProviderFactory, using environment variables as input
*/
Expand Down
5 changes: 0 additions & 5 deletions examples/traces/exporters/otlp_http_json.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,11 @@

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

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;

LoggerHolder::set(new Logger('otlp-example', [new StreamHandler('php://stderr')]));

$transport = (new OtlpHttpTransportFactory())->create('http://collector:4318/v1/traces', 'application/json');
$exporter = new SpanExporter($transport);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace OpenTelemetry\Example;

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

/**
* If you want/need to test or debug the creation of traces and spans without an instance of an exporter/collector,
Expand All @@ -24,7 +24,7 @@
/**
* Create the log directory
*/
$logDir = __DIR__ . '/../var/log';
$logDir = __DIR__ . '/var/log';
$logFile = $logDir . '/otel.log';
if (!is_dir($logDir) && !mkdir($logDir, 0744, true) && !is_dir($logDir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $logDir));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace OpenTelemetry\Example;

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

/**
* If you want to observe or debug the span data, which is sent to an exporter/collector,
Expand All @@ -29,7 +29,7 @@
/**
* Create the log directory
*/
$logDir = __DIR__ . '/../var/log';
$logDir = __DIR__ . '/var/log';
$logFile = $logDir . '/otel.log';
if (!is_dir($logDir) && !mkdir($logDir, 0744, true) && !is_dir($logDir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $logDir));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,25 @@

namespace OpenTelemetry\Example;

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

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\SDK\Trace\TracerProviderFactory;
use Psr\Log\LogLevel;

echo 'Starting SettingUpLogging example' . PHP_EOL;
echo 'Starting PSR-3 Logging example' . PHP_EOL;

//By default, opentelemetry's internal logging (errors, warnings, etc) will use `trigger_error`.
//You can instead provide a psr-3 logger to provide greater control of logging output:
LoggerHolder::set(
new Logger('otel-php', [new StreamHandler(STDOUT, LogLevel::DEBUG)])
);
putenv('OTEL_PHP_LOG_DESTINATION=psr3'); //or, do not set this at all.
putenv('OTEL_EXPORTER_OTLP_ENDPOINT=http://does-not-exist/endpoint'); //invalid endpoint, export will fail
putenv('OTEL_EXPORTER_OTLP_PROTOCOL=grpc');

$filename = __DIR__ . '/var/otel.log';
\OpenTelemetry\API\LoggerHolder::set(new \Monolog\Logger('otel', [new \Monolog\Handler\StreamHandler($filename)]));

$factory = new TracerProviderFactory();
$tracerProvider = $factory->create();

$tracer = $tracerProvider->getTracer('io.opentelemetry.contrib.php');
$span = $tracer->spanBuilder('root-span')->startSpan();
$span->end();
$tracerProvider->shutdown();

echo sprintf("Logs written to: %s\n", $filename);
34 changes: 34 additions & 0 deletions examples/troubleshooting/setting_up_logging.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\Example;

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

use Monolog\Logger;
use OpenTelemetry\SDK\Trace\TracerProviderFactory;

echo 'Starting Logging example' . PHP_EOL;

/**
* By default errors and warnings from the SDK itself (for example misconfiguration, exporter errors) will be sent to PHP's error_log.
* You can change that by setting OTEL_PHP_LOG_DESTINATION.
* Valid values for OTEL_PHP_LOG_DESTINATION: error_log, stdout, stderr, none, psr3, default
* (default = psr-3 if LoggerHolder::set called, otherwise error_log
*
* Note that PSR-3 logging will only work if a PSR-3 logger is registered in OpenTelemetry\API\LoggerHolder::set()
* If no PSR-3 logger is available, it will fall back to using error_log.
*/

putenv('OTEL_PHP_LOG_DESTINATION=stderr');
putenv('OTEL_EXPORTER_OTLP_ENDPOINT=http://does-not-exist/endpoint'); //invalid endpoint, export will fail
putenv('OTEL_EXPORTER_OTLP_PROTOCOL=grpc');

$factory = new TracerProviderFactory();
$tracerProvider = $factory->create();

$tracer = $tracerProvider->getTracer('io.opentelemetry.contrib.php');
$span = $tracer->spanBuilder('root-span')->startSpan();
$span->end();
$tracerProvider->shutdown();
13 changes: 13 additions & 0 deletions src/API/Behavior/Internal/LogWriter/ErrorLogWriter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\API\Behavior\Internal\LogWriter;

class ErrorLogWriter implements LogWriterInterface
{
public function write($level, string $message, array $context): void
{
error_log(Formatter::format($level, $message, $context));
}
}
37 changes: 37 additions & 0 deletions src/API/Behavior/Internal/LogWriter/Formatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\API\Behavior\Internal\LogWriter;

class Formatter
{
public static function format($level, string $message, array $context): string
{
$exception = (array_key_exists('exception', $context) && $context['exception'] instanceof \Throwable)
? $context['exception']
: null;
if ($exception) {
$message = sprintf(
'OpenTelemetry: [%s] %s [exception] %s%s%s',
$level,
$message,
$exception->getMessage(),
PHP_EOL,
$exception->getTraceAsString()
);
} else {
//get calling location, skipping over trait, formatter etc
$caller = debug_backtrace()[3];
$message = sprintf(
'OpenTelemetry: [%s] %s in %s(%s)',
$level,
$message,
$caller['file'],
$caller['line'],
);
}

return $message;
}
}
10 changes: 10 additions & 0 deletions src/API/Behavior/Internal/LogWriter/LogWriterInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\API\Behavior\Internal\LogWriter;

interface LogWriterInterface
{
public function write($level, string $message, array $context): void;
}
13 changes: 13 additions & 0 deletions src/API/Behavior/Internal/LogWriter/NoopLogWriter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace OpenTelemetry\API\Behavior\Internal\LogWriter;

class NoopLogWriter implements LogWriterInterface
{
public function write($level, string $message, array $context): void
{
//do nothing
}
}
Loading

0 comments on commit 73ff5ad

Please sign in to comment.