default logging to console (#899)

Rather than log nothing by default, log warnings and greater to console.
By providing a psr-3 logger, users can gain greater control over logging, including disabling it (via NullLogger)
This commit is contained in:
Brett McBride 2022-12-22 09:39:27 +11:00 committed by GitHub
parent c98866b3fa
commit 558e7ce30e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 104 additions and 11 deletions

View File

@ -5,14 +5,14 @@ require __DIR__ . '/../../../vendor/autoload.php';
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use OpenTelemetry\SDK\Common\Log\LoggerHolder;
use OpenTelemetry\API\Common\Log\LoggerHolder;
use OpenTelemetry\SDK\Trace\TracerProviderFactory;
use Psr\Log\LogLevel;
echo 'Starting SettingUpLogging example' . PHP_EOL;
//create a Logger, and register it with library's logger holder. The library will use this logger
//for all of its internal logging (errors, warnings, etc)
//By default, opentelemetry's internal logging (errors, warnings, etc) will be output to console.
//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)])
);

View File

@ -9,10 +9,40 @@ use Psr\Log\LogLevel;
trait LogsMessagesTrait
{
private static function shouldLog(string $level): bool
{
return in_array($level, [LogLevel::ERROR, LogLevel::WARNING, LogLevel::CRITICAL, LogLevel::EMERGENCY]);
}
private static function map(string $level)
{
switch ($level) {
case LogLevel::WARNING:
return E_USER_WARNING;
case LogLevel::ERROR:
case LogLevel::CRITICAL:
case LogLevel::EMERGENCY:
return E_USER_ERROR;
default:
return E_USER_NOTICE;
}
}
private static function doLog(string $level, string $message, array $context): void
{
$logger = LoggerHolder::get();
if ($logger !== null) {
$context['source'] = get_called_class();
LoggerHolder::get()->log($level, $message, $context);
$logger->log($level, $message, $context);
} elseif (self::shouldLog($level)) {
$message = sprintf(
'%s: %s in %s',
$message,
(array_key_exists('exception', $context) && $context['exception'] instanceof \Throwable) ? $context['exception']->getMessage() : '',
get_called_class()
);
trigger_error($message, self::map($level));
}
}
protected static function logDebug(string $message, array $context = []): void

View File

@ -21,13 +21,14 @@ final class LoggerHolder
/**
* @suppress PhanTypeMismatchReturnNullable
* @internal
*/
public static function get(): LoggerInterface
public static function get(): ?LoggerInterface
{
return self::$logger ?? new NullLogger();
return self::$logger;
}
public static function set(LoggerInterface $logger): void
public static function set(?LoggerInterface $logger): void
{
self::$logger = $logger;
}

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace OpenTelemetry\Tests\Unit\SDK\Behavior;
namespace OpenTelemetry\Tests\Unit\API\Behavior;
use OpenTelemetry\API\Behavior\LogsMessagesTrait;
use OpenTelemetry\API\Common\Log\LoggerHolder;
@ -30,6 +30,30 @@ class LogsMessagesTraitTest extends TestCase
LoggerHolder::unset();
}
public function test_defaults_to_trigger_error_with_warning(): void
{
$message = 'something went wrong';
LoggerHolder::unset();
$this->assertFalse(LoggerHolder::isSet());
$instance = $this->createInstance();
$this->expectWarning();
$this->expectWarningMessageMatches(sprintf('/%s/', $message));
$instance->run('logWarning', 'foo', ['exception' => new \Exception($message)]);
}
public function test_defaults_to_trigger_error_with_error(): void
{
$message = 'something went wrong';
LoggerHolder::unset();
$this->assertFalse(LoggerHolder::isSet());
$instance = $this->createInstance();
$this->expectError();
$this->expectErrorMessageMatches(sprintf('/%s/', $message));
$instance->run('logError', 'foo', ['exception' => new \Exception($message)]);
}
/**
* @testdox Proxies logging methods through to logger
* @dataProvider logLevelProvider
@ -60,9 +84,9 @@ class LogsMessagesTraitTest extends TestCase
return new class() {
use LogsMessagesTrait;
//accessor for protected trait methods
public function run(string $method, string $message): void
public function run(string $method, string $message, array $context = []): void
{
$this->{$method}($message);
$this->{$method}($message, $context);
}
};
}

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace OpenTelemetry\Tests\Unit\API\Trace\Propagation;
use OpenTelemetry\API\Common\Log\LoggerHolder;
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
use OpenTelemetry\API\Trace\SpanContext;
use OpenTelemetry\API\Trace\SpanContextInterface;
@ -14,6 +15,7 @@ use OpenTelemetry\Context\Context;
use OpenTelemetry\Context\ContextInterface;
use OpenTelemetry\SDK\Trace\Span;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
/**
* @covers \OpenTelemetry\API\Trace\Propagation\TraceContextPropagator
@ -32,6 +34,7 @@ class TraceContextPropagatorTest extends TestCase
protected function setUp(): void
{
LoggerHolder::set(new NullLogger());
$this->traceContextPropagator = TraceContextPropagator::getInstance();
$this->traceState = (new TraceState())->with('bar', 'baz')->with('foo', 'bar');
}

View File

@ -4,8 +4,10 @@ declare(strict_types=1);
namespace OpenTelemetry\Tests\API\Unit\Trace;
use OpenTelemetry\API\Common\Log\LoggerHolder;
use OpenTelemetry\API\Trace\TraceState;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use function str_repeat;
use function strlen;
@ -14,6 +16,11 @@ use function strlen;
*/
class TraceStateTest extends TestCase
{
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
}
public function test_get_tracestate_value(): void
{
$tracestate = new TraceState('vendor1=value1');

View File

@ -5,11 +5,13 @@ declare(strict_types=1);
namespace OpenTelemetry\Example\Unit\SDK\Metrics;
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
use OpenTelemetry\API\Common\Log\LoggerHolder;
use OpenTelemetry\API\Metrics\MeterInterface;
use OpenTelemetry\SDK\Common\Configuration\KnownValues;
use OpenTelemetry\SDK\Common\Configuration\Variables;
use OpenTelemetry\SDK\Metrics\MeterProviderFactory;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
/**
* @covers \OpenTelemetry\SDK\Metrics\MeterProviderFactory
@ -18,6 +20,11 @@ class MeterProviderFactoryTest extends TestCase
{
use EnvironmentVariables;
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
}
public function tearDown(): void
{
$this->restoreEnvironmentVariables();

View File

@ -6,6 +6,7 @@ namespace OpenTelemetry\Tests\Unit\SDK\Propagation;
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
use OpenTelemetry\API\Baggage\Propagation\BaggagePropagator;
use OpenTelemetry\API\Common\Log\LoggerHolder;
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
use OpenTelemetry\Context\Propagation\MultiTextMapPropagator;
use OpenTelemetry\Context\Propagation\NoopTextMapPropagator;
@ -14,6 +15,7 @@ use OpenTelemetry\SDK\Common\Configuration\KnownValues;
use OpenTelemetry\SDK\Common\Configuration\Variables;
use OpenTelemetry\SDK\Propagation\PropagatorFactory;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
/**
* @covers OpenTelemetry\SDK\Propagation\PropagatorFactory
@ -22,6 +24,11 @@ class PropagatorFactoryTest extends TestCase
{
use EnvironmentVariables;
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
}
public function tearDown(): void
{
$this->restoreEnvironmentVariables();

View File

@ -5,9 +5,11 @@ declare(strict_types=1);
namespace OpenTelemetry\Tests\Unit\SDK;
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
use OpenTelemetry\API\Common\Log\LoggerHolder;
use OpenTelemetry\SDK\Common\Configuration\Variables;
use OpenTelemetry\SDK\SdkAutoloader;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
/**
* @covers \OpenTelemetry\SDK\SdkAutoloader
@ -16,6 +18,11 @@ class SdkAutoloaderTest extends TestCase
{
use EnvironmentVariables;
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
}
public function tearDown(): void
{
SdkAutoloader::shutdown();

View File

@ -6,12 +6,14 @@ namespace OpenTelemetry\Tests\Unit\SDK\Trace\SpanExporter;
use Mockery;
use Mockery\Adapter\Phpunit\MockeryTestCase;
use OpenTelemetry\API\Common\Log\LoggerHolder;
use OpenTelemetry\SDK\Common\Export\TransportInterface;
use OpenTelemetry\SDK\Common\Future\CompletedFuture;
use OpenTelemetry\SDK\Common\Future\ErrorFuture;
use OpenTelemetry\SDK\Common\Future\FutureInterface;
use OpenTelemetry\SDK\Trace\SpanExporterInterface;
use OpenTelemetry\Tests\Unit\SDK\Util\SpanData;
use Psr\Log\NullLogger;
/**
* @psalm-suppress UndefinedInterfaceMethod
@ -23,6 +25,7 @@ abstract class AbstractExporterTest extends MockeryTestCase
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
$this->future = Mockery::mock(FutureInterface::class);
$this->future->allows([
'map' => $this->future,

View File

@ -31,6 +31,7 @@ use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
use OpenTelemetry\Tests\Unit\SDK\Util\TestClock;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
/**
* @covers \OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor
@ -41,6 +42,7 @@ class BatchSpanProcessorTest extends MockeryTestCase
protected function setUp(): void
{
LoggerHolder::set(new NullLogger());
$this->testClock = new TestClock();
ClockFactory::setDefault($this->testClock);

View File

@ -21,6 +21,7 @@ use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\Tests\Unit\SDK\Util\SpanData;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
/**
* @covers OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor
@ -43,6 +44,7 @@ class SimpleSpanProcessorTest extends MockeryTestCase
protected function setUp(): void
{
LoggerHolder::set(new NullLogger());
$this->readWriteSpan = Mockery::mock(ReadWriteSpanInterface::class);
$this->readableSpan = Mockery::mock(ReadableSpanInterface::class);