refactor sdk/api logging (#1105)
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.
This commit is contained in:
parent
197a7a4c2c
commit
73ff5adcb8
|
@ -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;
|
|
@ -4,9 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
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;
|
||||
|
@ -19,14 +16,9 @@ use OpenTelemetry\SDK\Common\Time\ClockFactory;
|
|||
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(
|
||||
|
|
|
@ -4,9 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
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;
|
||||
|
@ -16,14 +13,9 @@ use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory;
|
|||
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);
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@ use OpenTelemetry\Contrib\Otlp\OtlpUtil;
|
|||
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(
|
||||
|
|
|
@ -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;
|
||||
|
@ -25,8 +22,6 @@ require __DIR__ . '/../vendor/autoload.php';
|
|||
|
||||
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();
|
||||
|
|
|
@ -6,9 +6,6 @@ namespace OpenTelemetry\Example;
|
|||
|
||||
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;
|
||||
|
@ -16,8 +13,6 @@ 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);
|
||||
|
|
|
@ -13,8 +13,6 @@ use OpenTelemetry\Contrib\Otlp\SpanExporter;
|
|||
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';
|
||||
|
|
|
@ -8,8 +8,6 @@ use OpenTelemetry\SDK\Trace\TracerProviderFactory;
|
|||
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -6,16 +6,11 @@ namespace OpenTelemetry\Example;
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ namespace OpenTelemetry\Example;
|
|||
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -6,16 +6,11 @@ namespace OpenTelemetry\Example;
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
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,
|
||||
|
@ -24,7 +24,7 @@ use OpenTelemetry\SDK\Trace\TracerProvider;
|
|||
/**
|
||||
* 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));
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
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,
|
||||
|
@ -29,7 +29,7 @@ use OpenTelemetry\SDK\Trace\TracerProvider;
|
|||
/**
|
||||
* 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));
|
|
@ -4,23 +4,19 @@ declare(strict_types=1);
|
|||
|
||||
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();
|
||||
|
||||
|
@ -28,3 +24,5 @@ $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);
|
|
@ -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();
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\API\Behavior\Internal\LogWriter;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Psr3LogWriter implements LogWriterInterface
|
||||
{
|
||||
private LoggerInterface $logger;
|
||||
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function write($level, string $message, array $context): void
|
||||
{
|
||||
$this->logger->log($level, $message, $context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\API\Behavior\Internal\LogWriter;
|
||||
|
||||
class StreamLogWriter implements LogWriterInterface
|
||||
{
|
||||
private $stream;
|
||||
|
||||
public function __construct(string $destination)
|
||||
{
|
||||
$stream = fopen($destination, 'a');
|
||||
if ($stream) {
|
||||
$this->stream = $stream;
|
||||
} else {
|
||||
throw new \RuntimeException(sprintf('Unable to open %s for writing', $destination));
|
||||
}
|
||||
}
|
||||
|
||||
public function write($level, string $message, array $context): void
|
||||
{
|
||||
fwrite($this->stream, Formatter::format($level, $message, $context));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\API\Behavior\Internal;
|
||||
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\ErrorLogWriter;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\NoopLogWriter;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\Psr3LogWriter;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\StreamLogWriter;
|
||||
use OpenTelemetry\API\Globals;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
|
||||
class LogWriterFactory
|
||||
{
|
||||
private const OTEL_PHP_LOG_DESTINATION = 'OTEL_PHP_LOG_DESTINATION';
|
||||
|
||||
public function create(): LogWriterInterface
|
||||
{
|
||||
$dest = Globals::configurationResolver()->getEnum(self::OTEL_PHP_LOG_DESTINATION);
|
||||
//we might not have an SDK, so attempt to get from environment
|
||||
if (!$dest) {
|
||||
$dest = array_key_exists(self::OTEL_PHP_LOG_DESTINATION, $_SERVER)
|
||||
? $_SERVER[self::OTEL_PHP_LOG_DESTINATION]
|
||||
: getenv(self::OTEL_PHP_LOG_DESTINATION);
|
||||
}
|
||||
if (!$dest) {
|
||||
$dest = ini_get(self::OTEL_PHP_LOG_DESTINATION);
|
||||
}
|
||||
$logger = LoggerHolder::get();
|
||||
|
||||
switch ($dest) {
|
||||
case 'none':
|
||||
return new NoopLogWriter();
|
||||
case 'stderr':
|
||||
return new StreamLogWriter('php://stderr');
|
||||
case 'stdout':
|
||||
return new StreamLogWriter('php://stdout');
|
||||
case 'psr3':
|
||||
if ($logger) {
|
||||
return new Psr3LogWriter($logger);
|
||||
}
|
||||
error_log('OpenTelemetry: cannot use OTEL_PHP_LOG_DESTINATION=psr3 without providing a PSR-3 logger');
|
||||
//default to error log
|
||||
return new ErrorLogWriter();
|
||||
case 'error_log':
|
||||
return new ErrorLogWriter();
|
||||
default:
|
||||
if ($logger) {
|
||||
return new Psr3LogWriter($logger);
|
||||
}
|
||||
|
||||
return new ErrorLogWriter();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,16 +4,17 @@ declare(strict_types=1);
|
|||
|
||||
namespace OpenTelemetry\API\Behavior\Internal;
|
||||
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Logging utility functions for default (error_log) logging.
|
||||
* Logging utility functions for internal logging (of OpenTelemetry errors/warnings etc).
|
||||
* This is not part of SDK configuration to avoid creating a dependency on SDK from any package which does logging.
|
||||
* @todo this should be `@internal`, but deptrac is not happy with that.
|
||||
*/
|
||||
class Logging
|
||||
{
|
||||
private const VARIABLE_NAME = 'OTEL_LOG_LEVEL';
|
||||
private const OTEL_LOG_LEVEL = 'OTEL_LOG_LEVEL';
|
||||
private const DEFAULT_LEVEL = LogLevel::INFO;
|
||||
private const NONE = 'none';
|
||||
private const LEVELS = [
|
||||
|
@ -32,6 +33,19 @@ class Logging
|
|||
* The minimum log level. Messages with lower severity than this will be ignored.
|
||||
*/
|
||||
private static ?int $logLevel = null;
|
||||
private static ?LogWriterInterface $writer = null;
|
||||
|
||||
public static function setLogWriter(LogWriterInterface $writer): void
|
||||
{
|
||||
self::$writer = $writer;
|
||||
}
|
||||
|
||||
public static function logWriter(): LogWriterInterface
|
||||
{
|
||||
self::$writer ??= (new LogWriterFactory())->create();
|
||||
|
||||
return self::$writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get level priority from level name
|
||||
|
@ -53,30 +67,13 @@ class Logging
|
|||
return self::$logLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map PSR-3 levels to error_log levels.
|
||||
* Note that we should never use higher than E_USER_WARNING so that we do not break user applications.
|
||||
*/
|
||||
public static function map(string $level)
|
||||
{
|
||||
switch ($level) {
|
||||
case LogLevel::WARNING:
|
||||
case LogLevel::ERROR:
|
||||
case LogLevel::CRITICAL:
|
||||
case LogLevel::EMERGENCY:
|
||||
return E_USER_WARNING;
|
||||
default:
|
||||
return E_USER_NOTICE;
|
||||
}
|
||||
}
|
||||
|
||||
private static function getLogLevel(): int
|
||||
{
|
||||
$level = array_key_exists(self::VARIABLE_NAME, $_SERVER)
|
||||
? $_SERVER[self::VARIABLE_NAME]
|
||||
: getenv(self::VARIABLE_NAME);
|
||||
$level = array_key_exists(self::OTEL_LOG_LEVEL, $_SERVER)
|
||||
? $_SERVER[self::OTEL_LOG_LEVEL]
|
||||
: getenv(self::OTEL_LOG_LEVEL);
|
||||
if (!$level) {
|
||||
$level = ini_get(self::VARIABLE_NAME);
|
||||
$level = ini_get(self::OTEL_LOG_LEVEL);
|
||||
}
|
||||
if (!$level) {
|
||||
$level = self::DEFAULT_LEVEL;
|
||||
|
@ -88,5 +85,6 @@ class Logging
|
|||
public static function reset(): void
|
||||
{
|
||||
self::$logLevel = null;
|
||||
self::$writer = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ declare(strict_types=1);
|
|||
namespace OpenTelemetry\API\Behavior;
|
||||
|
||||
use OpenTelemetry\API\Behavior\Internal\Logging;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
trait LogsMessagesTrait
|
||||
|
@ -17,33 +16,10 @@ trait LogsMessagesTrait
|
|||
|
||||
private static function doLog(string $level, string $message, array $context): void
|
||||
{
|
||||
$logger = LoggerHolder::get();
|
||||
if ($logger !== null) {
|
||||
$writer = Logging::logWriter();
|
||||
if (self::shouldLog($level)) {
|
||||
$context['source'] = get_called_class();
|
||||
$logger->log($level, $message, $context);
|
||||
} elseif (self::shouldLog($level)) {
|
||||
$exception = (array_key_exists('exception', $context) && $context['exception'] instanceof \Throwable)
|
||||
? $context['exception']
|
||||
: null;
|
||||
if ($exception) {
|
||||
$message = sprintf(
|
||||
'%s: %s%s%s',
|
||||
$message,
|
||||
$exception->getMessage(),
|
||||
PHP_EOL,
|
||||
$exception->getTraceAsString()
|
||||
);
|
||||
} else {
|
||||
//get calling location, skipping over trait
|
||||
$caller = debug_backtrace()[1];
|
||||
$message = sprintf(
|
||||
'%s(%s): %s',
|
||||
$caller['file'],
|
||||
$caller['line'],
|
||||
$message,
|
||||
);
|
||||
}
|
||||
trigger_error($message, Logging::map($level));
|
||||
$writer->write($level, $message, $context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,4 +11,5 @@ interface ConfigurationResolverInterface
|
|||
public function getBoolean(string $name): ?bool;
|
||||
public function getInt(string $name): ?int;
|
||||
public function getList(string $name): array;
|
||||
public function getEnum(string $name): ?string;
|
||||
}
|
||||
|
|
|
@ -30,4 +30,9 @@ class NoopConfigurationResolver implements ConfigurationResolverInterface
|
|||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getEnum(string $name): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,4 +32,9 @@ class ConfigurationResolver implements ConfigurationResolverInterface
|
|||
{
|
||||
return Configuration::getList($name);
|
||||
}
|
||||
|
||||
public function getEnum(string $name): ?string
|
||||
{
|
||||
return Configuration::getEnum($name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,4 +116,5 @@ interface Defaults
|
|||
public const OTEL_PHP_INTERNAL_METRICS_ENABLED = 'false';
|
||||
public const OTEL_PHP_DISABLED_INSTRUMENTATIONS = [];
|
||||
public const OTEL_PHP_LOGS_PROCESSOR = 'batch';
|
||||
public const OTEL_PHP_LOG_DESTINATION = 'default';
|
||||
}
|
||||
|
|
|
@ -172,6 +172,11 @@ interface KnownValues
|
|||
self::VALUE_NONE,
|
||||
];
|
||||
public const OTEL_PHP_AUTOLOAD_ENABLED = self::VALUES_BOOLEAN;
|
||||
public const VALUE_ERROR_LOG = 'error_log';
|
||||
public const VALUE_STDERR = 'stderr';
|
||||
public const VALUE_STDOUT = 'stdout';
|
||||
public const VALUE_PSR3 = 'psr3';
|
||||
public const VALUE_EMPTY = '';
|
||||
public const VALUE_DETECTORS_ENVIRONMENT = 'env';
|
||||
public const VALUE_DETECTORS_HOST = 'host';
|
||||
public const VALUE_DETECTORS_OS = 'os';
|
||||
|
@ -192,4 +197,12 @@ interface KnownValues
|
|||
self::VALUE_DETECTORS_COMPOSER,
|
||||
self::VALUE_NONE,
|
||||
];
|
||||
public const OTEL_PHP_LOG_DESTINATION = [
|
||||
self::VALUE_ERROR_LOG,
|
||||
self::VALUE_STDERR,
|
||||
self::VALUE_STDOUT,
|
||||
self::VALUE_PSR3,
|
||||
self::VALUE_EMPTY,
|
||||
self::VALUE_NONE,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ interface ValueTypes
|
|||
{
|
||||
/**
|
||||
* General SDK Configuration
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#general-sdk-configuration
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#general-sdk-configuration
|
||||
*/
|
||||
public const OTEL_RESOURCE_ATTRIBUTES = VariableTypes::MAP;
|
||||
public const OTEL_SERVICE_NAME = VariableTypes::STRING;
|
||||
|
@ -22,7 +22,7 @@ interface ValueTypes
|
|||
public const OTEL_TRACES_SAMPLER_ARG = VariableTypes::MIXED;
|
||||
/**
|
||||
* Batch Span Processor
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#batch-span-processor
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#batch-span-processor
|
||||
*/
|
||||
public const OTEL_BSP_SCHEDULE_DELAY = VariableTypes::INTEGER;
|
||||
public const OTEL_BSP_EXPORT_TIMEOUT = VariableTypes::INTEGER;
|
||||
|
@ -30,6 +30,7 @@ interface ValueTypes
|
|||
public const OTEL_BSP_MAX_EXPORT_BATCH_SIZE = VariableTypes::INTEGER;
|
||||
/**
|
||||
* Batch LogRecord Processor
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#batch-logrecord-processor
|
||||
*/
|
||||
public const OTEL_BLRP_SCHEDULE_DELAY = VariableTypes::INTEGER;
|
||||
public const OTEL_BLRP_EXPORT_TIMEOUT = VariableTypes::INTEGER;
|
||||
|
@ -37,13 +38,13 @@ interface ValueTypes
|
|||
public const OTEL_BLRP_MAX_EXPORT_BATCH_SIZE = VariableTypes::INTEGER;
|
||||
/**
|
||||
* Attribute Limits
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#attribute-limits
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#attribute-limits
|
||||
*/
|
||||
public const OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = VariableTypes::INTEGER;
|
||||
public const OTEL_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
|
||||
/**
|
||||
* Span Limits
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#span-limits-
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#span-limits
|
||||
*/
|
||||
public const OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = VariableTypes::INTEGER;
|
||||
public const OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
|
||||
|
@ -51,9 +52,15 @@ interface ValueTypes
|
|||
public const OTEL_SPAN_LINK_COUNT_LIMIT = VariableTypes::INTEGER;
|
||||
public const OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
|
||||
public const OTEL_LINK_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
|
||||
/**
|
||||
* LogRecord Limits
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#logrecord-limits
|
||||
*/
|
||||
public const OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT = VariableTypes::INTEGER;
|
||||
public const OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT = VariableTypes::INTEGER;
|
||||
/**
|
||||
* OTLP Exporter
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/protocol/exporter.md#configuration-options
|
||||
*/
|
||||
// Endpoint
|
||||
public const OTEL_EXPORTER_OTLP_ENDPOINT = VariableTypes::STRING;
|
||||
|
@ -117,8 +124,10 @@ interface ValueTypes
|
|||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#language-specific-environment-variables
|
||||
*/
|
||||
public const OTEL_PHP_TRACES_PROCESSOR = VariableTypes::ENUM;
|
||||
public const OTEL_PHP_LOGS_PROCESSOR = VariableTypes::LIST;
|
||||
public const OTEL_PHP_DETECTORS = VariableTypes::LIST;
|
||||
public const OTEL_PHP_AUTOLOAD_ENABLED = VariableTypes::BOOL;
|
||||
public const OTEL_PHP_LOG_DESTINATION = VariableTypes::ENUM;
|
||||
public const OTEL_PHP_INTERNAL_METRICS_ENABLED = VariableTypes::BOOL;
|
||||
public const OTEL_PHP_DISABLED_INSTRUMENTATIONS = VariableTypes::LIST;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ interface Variables
|
|||
{
|
||||
/**
|
||||
* General SDK Configuration
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#general-sdk-configuration
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#general-sdk-configuration
|
||||
*/
|
||||
public const OTEL_RESOURCE_ATTRIBUTES = 'OTEL_RESOURCE_ATTRIBUTES';
|
||||
public const OTEL_SERVICE_NAME = 'OTEL_SERVICE_NAME';
|
||||
|
@ -23,7 +23,7 @@ interface Variables
|
|||
public const OTEL_SDK_DISABLED = 'OTEL_SDK_DISABLED';
|
||||
/**
|
||||
* Batch Span Processor
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#batch-span-processor
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#batch-span-processor
|
||||
*/
|
||||
public const OTEL_BSP_SCHEDULE_DELAY = 'OTEL_BSP_SCHEDULE_DELAY';
|
||||
public const OTEL_BSP_EXPORT_TIMEOUT = 'OTEL_BSP_EXPORT_TIMEOUT';
|
||||
|
@ -31,7 +31,7 @@ interface Variables
|
|||
public const OTEL_BSP_MAX_EXPORT_BATCH_SIZE = 'OTEL_BSP_MAX_EXPORT_BATCH_SIZE';
|
||||
/**
|
||||
* Batch LogRecord Processor
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#batch-logrecord-processor
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#batch-logrecord-processor
|
||||
*/
|
||||
public const OTEL_BLRP_SCHEDULE_DELAY = 'OTEL_BLRP_SCHEDULE_DELAY';
|
||||
public const OTEL_BLRP_EXPORT_TIMEOUT = 'OTEL_BLRP_EXPORT_TIMEOUT';
|
||||
|
@ -39,19 +39,19 @@ interface Variables
|
|||
public const OTEL_BLRP_MAX_EXPORT_BATCH_SIZE = 'OTEL_BLRP_MAX_EXPORT_BATCH_SIZE';
|
||||
/**
|
||||
* Attribute Limits
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#attribute-limits
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#attribute-limits
|
||||
*/
|
||||
public const OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT = 'OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT';
|
||||
public const OTEL_ATTRIBUTE_COUNT_LIMIT = 'OTEL_ATTRIBUTE_COUNT_LIMIT';
|
||||
/**
|
||||
* LogRecord limits
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#logrecord-limits
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#logrecord-limits
|
||||
*/
|
||||
public const OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT = 'OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT';
|
||||
public const OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT = 'OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT';
|
||||
/**
|
||||
* Span Limits
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#span-limits-
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#span-limits
|
||||
*/
|
||||
public const OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = 'OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT';
|
||||
public const OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = 'OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT';
|
||||
|
@ -61,7 +61,7 @@ interface Variables
|
|||
public const OTEL_LINK_ATTRIBUTE_COUNT_LIMIT = 'OTEL_LINK_ATTRIBUTE_COUNT_LIMIT';
|
||||
/**
|
||||
* OTLP Exporter
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/protocol/exporter.md#configuration-options
|
||||
*/
|
||||
// Endpoint
|
||||
public const OTEL_EXPORTER_OTLP_ENDPOINT = 'OTEL_EXPORTER_OTLP_ENDPOINT';
|
||||
|
@ -100,27 +100,28 @@ interface Variables
|
|||
public const OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'OTEL_EXPORTER_OTLP_LOGS_PROTOCOL';
|
||||
/**
|
||||
* Zipkin Exporter
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#zipkin-exporter
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#zipkin-exporter
|
||||
*/
|
||||
public const OTEL_EXPORTER_ZIPKIN_ENDPOINT = 'OTEL_EXPORTER_ZIPKIN_ENDPOINT';
|
||||
public const OTEL_EXPORTER_ZIPKIN_TIMEOUT = 'OTEL_EXPORTER_ZIPKIN_TIMEOUT';
|
||||
public const OTEL_EXPORTER_ZIPKIN_PROTOCOL = 'OTEL_EXPORTER_ZIPKIN_PROTOCOL';
|
||||
/**
|
||||
* Prometheus Exporter
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#prometheus-exporter
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#prometheus-exporter
|
||||
*/
|
||||
public const OTEL_EXPORTER_PROMETHEUS_HOST = 'OTEL_EXPORTER_PROMETHEUS_HOST';
|
||||
public const OTEL_EXPORTER_PROMETHEUS_PORT = 'OTEL_EXPORTER_PROMETHEUS_PORT';
|
||||
/**
|
||||
* Exporter Selection
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#exporter-selection
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#exporter-selection
|
||||
*/
|
||||
public const OTEL_TRACES_EXPORTER = 'OTEL_TRACES_EXPORTER';
|
||||
public const OTEL_METRICS_EXPORTER = 'OTEL_METRICS_EXPORTER';
|
||||
public const OTEL_LOGS_EXPORTER = 'OTEL_LOGS_EXPORTER';
|
||||
/**
|
||||
* Metrics SDK Configuration
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#metrics-sdk-configuration
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#metrics-sdk-configuration
|
||||
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#periodic-exporting-metricreader
|
||||
*/
|
||||
public const OTEL_METRICS_EXEMPLAR_FILTER = 'OTEL_METRICS_EXEMPLAR_FILTER';
|
||||
public const OTEL_METRIC_EXPORT_INTERVAL = 'OTEL_METRIC_EXPORT_INTERVAL';
|
||||
|
@ -133,6 +134,7 @@ interface Variables
|
|||
*/
|
||||
public const OTEL_PHP_TRACES_PROCESSOR = 'OTEL_PHP_TRACES_PROCESSOR';
|
||||
public const OTEL_PHP_LOGS_PROCESSOR = 'OTEL_PHP_LOGS_PROCESSOR';
|
||||
public const OTEL_PHP_LOG_DESTINATION = 'OTEL_PHP_LOG_DESTINATION';
|
||||
public const OTEL_PHP_DETECTORS = 'OTEL_PHP_DETECTORS';
|
||||
public const OTEL_PHP_AUTOLOAD_ENABLED = 'OTEL_PHP_AUTOLOAD_ENABLED';
|
||||
public const OTEL_PHP_INTERNAL_METRICS_ENABLED = 'OTEL_PHP_INTERNAL_METRICS_ENABLED'; //whether the SDK should emit its own metrics
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Tests\Unit\API\Behavior\Internal;
|
||||
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\Formatter;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \OpenTelemetry\API\Behavior\Internal\LogWriter\Formatter
|
||||
*/
|
||||
class FormatterTest extends TestCase
|
||||
{
|
||||
public function test_no_exception_contains_code_location(): void
|
||||
{
|
||||
$formatted = Formatter::format('error', 'hello', []);
|
||||
$this->assertStringContainsString('OpenTelemetry: [error] hello in', $formatted);
|
||||
}
|
||||
|
||||
public function test_exception_contains_stack_trace(): void
|
||||
{
|
||||
$formatted = Formatter::format('error', 'hello', ['exception' => new \Exception('kaboom')]);
|
||||
$this->assertStringContainsString('OpenTelemetry: [error] hello [exception] kaboom', $formatted);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OpenTelemetry\Tests\Unit\API\Behavior\Internal;
|
||||
|
||||
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\ErrorLogWriter;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\NoopLogWriter;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\Psr3LogWriter;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\StreamLogWriter;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriterFactory;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* @covers \OpenTelemetry\API\Behavior\Internal\LogWriterFactory
|
||||
*/
|
||||
class LogWriterFactoryTest extends TestCase
|
||||
{
|
||||
use EnvironmentVariables;
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
self::restoreEnvironmentVariables();
|
||||
LoggerHolder::unset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider logDestinationProvider
|
||||
* @psalm-suppress ArgumentTypeCoercion
|
||||
*/
|
||||
public function test_log_destination_from_env(string $value, string $expected): void
|
||||
{
|
||||
$this->setEnvironmentVariable('OTEL_PHP_LOG_DESTINATION', $value);
|
||||
$this->assertInstanceOf($expected, (new LogWriterFactory())->create());
|
||||
}
|
||||
|
||||
public static function logDestinationProvider(): array
|
||||
{
|
||||
return [
|
||||
['error_log', ErrorLogWriter::class],
|
||||
['stdout', StreamLogWriter::class],
|
||||
['stderr', StreamLogWriter::class],
|
||||
['none', NoopLogWriter::class],
|
||||
['', ErrorLogWriter::class],
|
||||
];
|
||||
}
|
||||
|
||||
public function test_psr3_log_destination(): void
|
||||
{
|
||||
LoggerHolder::set($this->createMock(LoggerInterface::class));
|
||||
$this->assertInstanceOf(Psr3LogWriter::class, (new LogWriterFactory())->create());
|
||||
}
|
||||
}
|
|
@ -6,12 +6,10 @@ namespace OpenTelemetry\Tests\Unit\API\Behavior;
|
|||
|
||||
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
|
||||
use OpenTelemetry\API\Behavior\Internal\Logging;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
|
||||
use OpenTelemetry\API\Behavior\LogsMessagesTrait;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
use PHPUnit\Framework\Exception as PHPUnitFrameworkException;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
|
@ -21,54 +19,42 @@ class LogsMessagesTraitTest extends TestCase
|
|||
{
|
||||
use EnvironmentVariables;
|
||||
|
||||
// @var LoggerInterface|MockObject $logger
|
||||
protected MockObject $logger;
|
||||
protected MockObject $writer;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
LoggerHolder::set($this->logger);
|
||||
$this->writer = $this->createMock(LogWriterInterface::class);
|
||||
Logging::setLogWriter($this->writer);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
LoggerHolder::unset();
|
||||
Logging::reset();
|
||||
$this->restoreEnvironmentVariables();
|
||||
}
|
||||
|
||||
public function test_defaults_to_trigger_error_with_warning(): void
|
||||
/**
|
||||
* @dataProvider logProvider
|
||||
*/
|
||||
public function test_log(string $method, string $expectedLevel): void
|
||||
{
|
||||
$message = 'something went wrong';
|
||||
LoggerHolder::unset();
|
||||
$this->assertFalse(LoggerHolder::isSet());
|
||||
$instance = $this->createInstance();
|
||||
|
||||
$this->expectException(PHPUnitFrameworkException::class);
|
||||
$this->expectExceptionMessageMatches('/LogsMessagesTraitTest->test_defaults_to_trigger_error_with_warning()/');
|
||||
$instance->run('logWarning', 'foo', ['exception' => new \Exception($message)]);
|
||||
$this->writer->expects($this->once())->method('write')->with(
|
||||
$this->equalTo($expectedLevel),
|
||||
$this->stringContains('foo'),
|
||||
$this->anything()
|
||||
);
|
||||
|
||||
$instance->run($method, 'foo', ['exception' => new \Exception('bang')]);
|
||||
}
|
||||
|
||||
public function test_defaults_to_trigger_error_with_error(): void
|
||||
public static function logProvider(): array
|
||||
{
|
||||
$message = 'something went wrong';
|
||||
LoggerHolder::unset();
|
||||
$this->assertFalse(LoggerHolder::isSet());
|
||||
$instance = $this->createInstance();
|
||||
|
||||
$this->expectException(PHPUnitFrameworkException::class);
|
||||
$this->expectExceptionMessageMatches(sprintf('/%s/', $message));
|
||||
$instance->run('logError', 'foo', ['exception' => new \Exception($message)]);
|
||||
}
|
||||
|
||||
public function test_error_log_without_exception_contains_code_location(): void
|
||||
{
|
||||
LoggerHolder::unset();
|
||||
$this->assertFalse(LoggerHolder::isSet());
|
||||
$instance = $this->createInstance();
|
||||
|
||||
$this->expectException(PHPUnitFrameworkException::class);
|
||||
$this->expectExceptionMessageMatches(sprintf('/%s\(/', addcslashes(__FILE__, '/')));
|
||||
$instance->run('logWarning', 'no exception here');
|
||||
return [
|
||||
['logWarning', 'warning'],
|
||||
['logError', 'error'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +64,7 @@ class LogsMessagesTraitTest extends TestCase
|
|||
public function test_log_methods(string $method, string $expectedLogLevel): void
|
||||
{
|
||||
$instance = $this->createInstance();
|
||||
$this->logger->expects($this->once())->method('log')->with(
|
||||
$this->writer->expects($this->once())->method('write')->with(
|
||||
$this->equalTo($expectedLogLevel),
|
||||
$this->equalTo('foo'),
|
||||
);
|
||||
|
@ -99,15 +85,14 @@ class LogsMessagesTraitTest extends TestCase
|
|||
/**
|
||||
* @dataProvider otelLogLevelProvider
|
||||
*/
|
||||
public function test_error_log_with_configured_otel_log_level(string $otelLogLevel, string $method, bool $expected): void
|
||||
public function test_logging_respects_configured_otel_log_level(string $otelLogLevel, string $method, bool $expected): void
|
||||
{
|
||||
LoggerHolder::unset();
|
||||
$this->setEnvironmentVariable('OTEL_LOG_LEVEL', $otelLogLevel);
|
||||
$instance = $this->createInstance();
|
||||
if ($expected === true) {
|
||||
$this->expectException(PHPUnitFrameworkException::class);
|
||||
$this->writer->expects($this->once())->method('write');
|
||||
} else {
|
||||
$this->assertTrue(true, 'dummy assertion');
|
||||
$this->writer->expects($this->never())->method('write');
|
||||
}
|
||||
$instance->run($method, 'test message');
|
||||
}
|
||||
|
@ -124,8 +109,6 @@ class LogsMessagesTraitTest extends TestCase
|
|||
|
||||
private function createInstance(): object
|
||||
{
|
||||
Logging::reset();
|
||||
|
||||
return new class() {
|
||||
use LogsMessagesTrait;
|
||||
//accessor for protected trait methods
|
||||
|
|
|
@ -116,7 +116,7 @@ class ScopeTest extends TestCase
|
|||
$scope['key'] = 'value';
|
||||
$scope = $storage->scope();
|
||||
$this->assertNotNull($scope);
|
||||
$this->assertArrayHasKey('key', $scope);
|
||||
$this->assertArrayHasKey('key', $scope); /** @phpstan-ignore-line */
|
||||
$this->assertSame('value', $scope['key']);
|
||||
|
||||
unset($scope['key']);
|
||||
|
|
|
@ -8,7 +8,8 @@ use InvalidArgumentException;
|
|||
use LogicException;
|
||||
use Mockery;
|
||||
use Mockery\Adapter\Phpunit\MockeryTestCase;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
use OpenTelemetry\API\Behavior\Internal\Logging;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
|
||||
use OpenTelemetry\Context\Context;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Common\Future\CompletedFuture;
|
||||
|
@ -26,9 +27,8 @@ use OpenTelemetry\SDK\Metrics\StalenessHandler\ImmediateStalenessHandlerFactory;
|
|||
use OpenTelemetry\SDK\Metrics\View\CriteriaViewRegistry;
|
||||
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
|
||||
use OpenTelemetry\Tests\Unit\SDK\Util\TestClock;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LogLevel;
|
||||
use Psr\Log\NullLogger;
|
||||
|
||||
/**
|
||||
* @covers \OpenTelemetry\SDK\Logs\Processor\BatchLogRecordProcessor
|
||||
|
@ -36,10 +36,13 @@ use Psr\Log\NullLogger;
|
|||
class BatchLogRecordProcessorTest extends MockeryTestCase
|
||||
{
|
||||
private TestClock $testClock;
|
||||
/** @var LogWriterInterface&MockObject $logWriter */
|
||||
private LogWriterInterface $logWriter;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
LoggerHolder::set(new NullLogger());
|
||||
$this->logWriter = $this->createMock(LogWriterInterface::class);
|
||||
Logging::setLogWriter($this->logWriter);
|
||||
$this->testClock = new TestClock();
|
||||
|
||||
ClockFactory::setDefault($this->testClock);
|
||||
|
@ -48,6 +51,7 @@ class BatchLogRecordProcessorTest extends MockeryTestCase
|
|||
protected function tearDown(): void
|
||||
{
|
||||
ClockFactory::setDefault(null);
|
||||
Logging::reset();
|
||||
}
|
||||
|
||||
public function test_export_batch_size_met(): void
|
||||
|
@ -327,22 +331,14 @@ class BatchLogRecordProcessorTest extends MockeryTestCase
|
|||
$exporter->method('forceFlush')->willReturn(true);
|
||||
$exporter->method('export')->willThrowException(new LogicException());
|
||||
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$logger->expects($this->once())->method('log')->with(LogLevel::ERROR);
|
||||
$this->logWriter->expects($this->once())->method('write')->with(LogLevel::ERROR);
|
||||
|
||||
$processor = new BatchLogRecordProcessor($exporter, $this->testClock);
|
||||
|
||||
$record = $this->createMock(ReadWriteLogRecord::class);
|
||||
$processor->onEmit($record);
|
||||
|
||||
$previousLogger = LoggerHolder::get();
|
||||
LoggerHolder::set($logger);
|
||||
|
||||
try {
|
||||
$processor->forceFlush();
|
||||
} finally {
|
||||
LoggerHolder::set($previousLogger);
|
||||
}
|
||||
$processor->forceFlush();
|
||||
}
|
||||
|
||||
public function test_throwing_exporter_flush(): void
|
||||
|
@ -371,22 +367,14 @@ class BatchLogRecordProcessorTest extends MockeryTestCase
|
|||
});
|
||||
$exporter->method('shutdown')->willThrowException(new LogicException());
|
||||
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$logger->expects($this->once())->method('log')->with(LogLevel::ERROR);
|
||||
$this->logWriter->expects($this->once())->method('write')->with(LogLevel::ERROR);
|
||||
|
||||
$processor = new BatchLogRecordProcessor($exporter, $this->testClock);
|
||||
|
||||
$record = $this->createMock(ReadWriteLogRecord::class);
|
||||
$processor->onEmit($record);
|
||||
|
||||
$previousLogger = LoggerHolder::get();
|
||||
LoggerHolder::set($logger);
|
||||
|
||||
try {
|
||||
$processor->forceFlush();
|
||||
} finally {
|
||||
LoggerHolder::set($previousLogger);
|
||||
}
|
||||
$processor->forceFlush();
|
||||
}
|
||||
|
||||
public function test_throwing_exporter_flush_rethrows_in_original_caller(): void
|
||||
|
|
|
@ -7,7 +7,8 @@ namespace OpenTelemetry\Tests\Unit\SDK\Resource;
|
|||
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
|
||||
use Generator;
|
||||
use InvalidArgumentException;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
use OpenTelemetry\API\Behavior\Internal\Logging;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
use OpenTelemetry\SDK\Registry;
|
||||
use OpenTelemetry\SDK\Resource\ResourceDetectorInterface;
|
||||
|
@ -15,7 +16,6 @@ use OpenTelemetry\SDK\Resource\ResourceInfo;
|
|||
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* @covers \OpenTelemetry\SDK\Resource\ResourceInfoFactory
|
||||
|
@ -24,20 +24,20 @@ class ResourceInfoFactoryTest extends TestCase
|
|||
{
|
||||
use EnvironmentVariables;
|
||||
|
||||
/** @var LoggerInterface&MockObject $logger */
|
||||
private LoggerInterface $logger;
|
||||
/** @var LogWriterInterface&MockObject $logWriter */
|
||||
private LogWriterInterface $logWriter;
|
||||
private const UNDEFINED = '__undefined';
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
LoggerHolder::set($this->logger);
|
||||
$this->logWriter = $this->createMock(LogWriterInterface::class);
|
||||
Logging::setLogWriter($this->logWriter);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
$this->restoreEnvironmentVariables();
|
||||
LoggerHolder::unset();
|
||||
Logging::reset();
|
||||
}
|
||||
|
||||
public function test_empty_resource(): void
|
||||
|
@ -189,7 +189,7 @@ class ResourceInfoFactoryTest extends TestCase
|
|||
|
||||
public function test_logs_warning_for_unknown_detector(): void
|
||||
{
|
||||
$this->logger->expects($this->once())->method('log')->with($this->equalTo('warning'));
|
||||
$this->logWriter->expects($this->once())->method('write')->with($this->equalTo('warning'));
|
||||
$this->setEnvironmentVariable('OTEL_PHP_DETECTORS', 'does-not-exist');
|
||||
|
||||
ResourceInfoFactory::defaultResource();
|
||||
|
|
|
@ -9,7 +9,8 @@ use InvalidArgumentException;
|
|||
use LogicException;
|
||||
use Mockery;
|
||||
use Mockery\Adapter\Phpunit\MockeryTestCase;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
use OpenTelemetry\API\Behavior\Internal\Logging;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
|
||||
use OpenTelemetry\API\Trace as API;
|
||||
use OpenTelemetry\Context\Context;
|
||||
use OpenTelemetry\SDK\Common\Attribute\Attributes;
|
||||
|
@ -30,9 +31,8 @@ use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
|
|||
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessorBuilder;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
|
||||
use OpenTelemetry\Tests\Unit\SDK\Util\TestClock;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LogLevel;
|
||||
use Psr\Log\NullLogger;
|
||||
|
||||
/**
|
||||
* @covers \OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor
|
||||
|
@ -40,10 +40,13 @@ use Psr\Log\NullLogger;
|
|||
class BatchSpanProcessorTest extends MockeryTestCase
|
||||
{
|
||||
private TestClock $testClock;
|
||||
/** @var LogWriterInterface&MockObject $logWriter */
|
||||
private LogWriterInterface $logWriter;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
LoggerHolder::set(new NullLogger());
|
||||
$this->logWriter = $this->createMock(LogWriterInterface::class);
|
||||
Logging::setLogWriter($this->logWriter);
|
||||
$this->testClock = new TestClock();
|
||||
|
||||
ClockFactory::setDefault($this->testClock);
|
||||
|
@ -52,6 +55,7 @@ class BatchSpanProcessorTest extends MockeryTestCase
|
|||
protected function tearDown(): void
|
||||
{
|
||||
ClockFactory::setDefault(null);
|
||||
Logging::reset();
|
||||
}
|
||||
|
||||
public function test_export_batch_size_met(): void
|
||||
|
@ -373,8 +377,7 @@ class BatchSpanProcessorTest extends MockeryTestCase
|
|||
$exporter->method('forceFlush')->willReturn(true);
|
||||
$exporter->method('export')->willThrowException(new LogicException());
|
||||
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$logger->expects($this->once())->method('log')->with(LogLevel::ERROR);
|
||||
$this->logWriter->expects($this->once())->method('write')->with(LogLevel::ERROR);
|
||||
|
||||
$processor = new BatchSpanProcessor($exporter, $this->testClock);
|
||||
|
||||
|
@ -382,14 +385,7 @@ class BatchSpanProcessorTest extends MockeryTestCase
|
|||
$processor->onStart($span, Context::getCurrent());
|
||||
$processor->onEnd($span);
|
||||
|
||||
$previousLogger = LoggerHolder::get();
|
||||
LoggerHolder::set($logger);
|
||||
|
||||
try {
|
||||
$processor->forceFlush();
|
||||
} finally {
|
||||
LoggerHolder::set($previousLogger);
|
||||
}
|
||||
$processor->forceFlush();
|
||||
}
|
||||
|
||||
public function test_throwing_exporter_flush(): void
|
||||
|
@ -420,8 +416,7 @@ class BatchSpanProcessorTest extends MockeryTestCase
|
|||
});
|
||||
$exporter->method('shutdown')->willThrowException(new LogicException());
|
||||
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$logger->expects($this->once())->method('log')->with(LogLevel::ERROR);
|
||||
$this->logWriter->expects($this->once())->method('write')->with(LogLevel::ERROR);
|
||||
|
||||
$processor = new BatchSpanProcessor($exporter, $this->testClock);
|
||||
|
||||
|
@ -429,14 +424,7 @@ class BatchSpanProcessorTest extends MockeryTestCase
|
|||
$processor->onStart($span, Context::getCurrent());
|
||||
$processor->onEnd($span);
|
||||
|
||||
$previousLogger = LoggerHolder::get();
|
||||
LoggerHolder::set($logger);
|
||||
|
||||
try {
|
||||
$processor->forceFlush();
|
||||
} finally {
|
||||
LoggerHolder::set($previousLogger);
|
||||
}
|
||||
$processor->forceFlush();
|
||||
}
|
||||
|
||||
public function test_throwing_exporter_flush_rethrows_in_original_caller(): void
|
||||
|
|
|
@ -8,7 +8,8 @@ use LogicException;
|
|||
use Mockery;
|
||||
use Mockery\Adapter\Phpunit\MockeryTestCase;
|
||||
use Mockery\MockInterface;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
use OpenTelemetry\API\Behavior\Internal\Logging;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
|
||||
use OpenTelemetry\API\Trace\SpanContext;
|
||||
use OpenTelemetry\API\Trace\SpanContextInterface;
|
||||
use OpenTelemetry\API\Trace\SpanContextValidator;
|
||||
|
@ -20,9 +21,8 @@ use OpenTelemetry\SDK\Trace\ReadWriteSpanInterface;
|
|||
use OpenTelemetry\SDK\Trace\SpanExporterInterface;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
|
||||
use OpenTelemetry\Tests\Unit\SDK\Util\SpanData;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Psr\Log\LogLevel;
|
||||
use Psr\Log\NullLogger;
|
||||
|
||||
/**
|
||||
* @covers \OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor
|
||||
|
@ -39,13 +39,16 @@ class SimpleSpanProcessorTest extends MockeryTestCase
|
|||
|
||||
/** @var MockInterface&ReadableSpanInterface */
|
||||
private $readableSpan;
|
||||
/** @var LogWriterInterface&MockObject $logWriter */
|
||||
private LogWriterInterface $logWriter;
|
||||
|
||||
private SpanContextInterface $sampledSpanContext;
|
||||
private SpanContextInterface $nonSampledSpanContext;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
LoggerHolder::set(new NullLogger());
|
||||
$this->logWriter = $this->createMock(LogWriterInterface::class);
|
||||
Logging::setLogWriter($this->logWriter);
|
||||
$this->readWriteSpan = Mockery::mock(ReadWriteSpanInterface::class);
|
||||
$this->readableSpan = Mockery::mock(ReadableSpanInterface::class);
|
||||
|
||||
|
@ -61,6 +64,11 @@ class SimpleSpanProcessorTest extends MockeryTestCase
|
|||
$this->simpleSpanProcessor = new SimpleSpanProcessor($this->spanExporter);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
Logging::reset();
|
||||
}
|
||||
|
||||
public function test_on_start(): void
|
||||
{
|
||||
$this->simpleSpanProcessor->onStart($this->readWriteSpan, Context::getRoot());
|
||||
|
@ -143,23 +151,15 @@ class SimpleSpanProcessorTest extends MockeryTestCase
|
|||
$exporter->method('forceFlush')->willReturn(true);
|
||||
$exporter->method('export')->willThrowException(new LogicException());
|
||||
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$logger->expects($this->once())->method('log')->with(LogLevel::ERROR);
|
||||
$this->logWriter->expects($this->once())->method('write')->with(LogLevel::ERROR);
|
||||
|
||||
$processor = new SimpleSpanProcessor($exporter);
|
||||
|
||||
$this->readableSpan->expects('getContext')->andReturn($this->sampledSpanContext);
|
||||
$this->readableSpan->expects('toSpanData')->andReturn(new SpanData());
|
||||
|
||||
$previousLogger = LoggerHolder::get();
|
||||
LoggerHolder::set($logger);
|
||||
|
||||
try {
|
||||
$processor->onStart($this->readWriteSpan, Context::getCurrent());
|
||||
$processor->onEnd($this->readableSpan);
|
||||
} finally {
|
||||
LoggerHolder::set($previousLogger);
|
||||
}
|
||||
$processor->onStart($this->readWriteSpan, Context::getCurrent());
|
||||
$processor->onEnd($this->readableSpan);
|
||||
}
|
||||
|
||||
public function test_throwing_exporter_flush(): void
|
||||
|
|
|
@ -9,7 +9,8 @@ use Exception;
|
|||
use Mockery;
|
||||
use Mockery\Adapter\Phpunit\MockeryTestCase;
|
||||
use Mockery\MockInterface;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
use OpenTelemetry\API\Behavior\Internal\Logging;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
|
||||
use OpenTelemetry\API\Trace as API;
|
||||
use OpenTelemetry\API\Trace\NonRecordingSpan;
|
||||
use OpenTelemetry\API\Trace\SpanContext;
|
||||
|
@ -38,7 +39,7 @@ use OpenTelemetry\SDK\Trace\SpanLimitsBuilder;
|
|||
use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
|
||||
use OpenTelemetry\SDK\Trace\StatusData;
|
||||
use OpenTelemetry\Tests\Unit\SDK\Util\TestClock;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use function range;
|
||||
use function str_repeat;
|
||||
|
||||
|
@ -58,7 +59,8 @@ class SpanTest extends MockeryTestCase
|
|||
|
||||
/** @var MockInterface&SpanProcessorInterface */
|
||||
private $spanProcessor;
|
||||
private $logger;
|
||||
/** @var LogWriterInterface&MockObject $logWriter */
|
||||
private LogWriterInterface $logWriter;
|
||||
|
||||
private IdGeneratorInterface $idGenerator;
|
||||
private ResourceInfo $resource;
|
||||
|
@ -98,14 +100,15 @@ class SpanTest extends MockeryTestCase
|
|||
);
|
||||
|
||||
ClockFactory::setDefault($this->testClock);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
LoggerHolder::set($this->logger);
|
||||
$this->logWriter = $this->createMock(LogWriterInterface::class);
|
||||
Logging::setLogWriter($this->logWriter);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
ClockFactory::setDefault(null);
|
||||
LoggerHolder::unset();
|
||||
Logging::reset();
|
||||
// LoggerHolder::unset();
|
||||
}
|
||||
|
||||
// region API
|
||||
|
@ -496,8 +499,8 @@ class SpanTest extends MockeryTestCase
|
|||
*/
|
||||
public function test_set_attribute_drops_non_homogeneous_array(array $values): void
|
||||
{
|
||||
$this->logger->expects($this->once())
|
||||
->method('log')
|
||||
$this->logWriter->expects($this->once())
|
||||
->method('write')
|
||||
->with(
|
||||
$this->equalTo('warning'),
|
||||
$this->stringContains('non-homogeneous')
|
||||
|
|
|
@ -5,14 +5,15 @@ declare(strict_types=1);
|
|||
namespace OpenTelemetry\Tests\Unit\SDK\Trace;
|
||||
|
||||
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
|
||||
use OpenTelemetry\API\LoggerHolder;
|
||||
use OpenTelemetry\API\Behavior\Internal\Logging;
|
||||
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
|
||||
use OpenTelemetry\API\Trace\NoopTracerProvider;
|
||||
use OpenTelemetry\SDK\Trace\ExporterFactory;
|
||||
use OpenTelemetry\SDK\Trace\SamplerFactory;
|
||||
use OpenTelemetry\SDK\Trace\SpanProcessorFactory;
|
||||
use OpenTelemetry\SDK\Trace\TracerProviderFactory;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* @covers \OpenTelemetry\SDK\Trace\TracerProviderFactory
|
||||
|
@ -21,17 +22,18 @@ class TracerProviderFactoryTest extends TestCase
|
|||
{
|
||||
use EnvironmentVariables;
|
||||
|
||||
private $logger;
|
||||
/** @var LogWriterInterface&MockObject $logWriter */
|
||||
private LogWriterInterface $logWriter;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
LoggerHolder::set($this->logger);
|
||||
$this->logWriter = $this->createMock(LogWriterInterface::class);
|
||||
Logging::setLogWriter($this->logWriter);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
LoggerHolder::unset();
|
||||
Logging::reset();
|
||||
$this->restoreEnvironmentVariables();
|
||||
}
|
||||
|
||||
|
@ -64,7 +66,7 @@ class TracerProviderFactoryTest extends TestCase
|
|||
$spanProcessorFactory->expects($this->once())
|
||||
->method('create')
|
||||
->willThrowException(new \InvalidArgumentException('foo'));
|
||||
$this->logger->expects($this->atLeast(3))->method('log');
|
||||
$this->logWriter->expects($this->atLeast(3))->method('write');
|
||||
|
||||
$factory = new TracerProviderFactory($exporterFactory, $samplerFactory, $spanProcessorFactory);
|
||||
$factory->create();
|
||||
|
|
Loading…
Reference in New Issue