Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Otel->Elatic log writer (#151) #154

Merged
merged 4 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions prod/native/extension/code/ModuleFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "ModuleFunctions.h"
#include "ConfigurationStorage.h"
#include "LoggerInterface.h"
#include "LogFeature.h"
#include "RequestScope.h"
#include "ModuleGlobals.h"
#include "ModuleFunctionsImpl.h"
Expand Down Expand Up @@ -100,7 +101,7 @@ PHP_FUNCTION(elastic_otel_log) {
Z_PARAM_STRING(message, messageLength)
ZEND_PARSE_PARAMETERS_END();

ELASTICAPM_G(globals)->logger_->printf(static_cast<LogLevel>(level), PRsv " " PRsv " %d " PRsv " " PRsv, PRcsvArg(category, categoryLength), PRcsvArg(file, fileLength), line, PRcsvArg(func, funcLength), PRcsvArg(message, messageLength));
ELASTICAPM_G(globals)->logger_->printf(static_cast<LogLevel>(level), "[" PRsv "] [" PRsv ":%d] [" PRsv "] " PRsv, PRcsvArg(category, categoryLength), PRcsvArg(file, fileLength), line, PRcsvArg(func, funcLength), PRcsvArg(message, messageLength));
}
/* }}} */

Expand Down Expand Up @@ -154,9 +155,10 @@ PHP_FUNCTION(elastic_otel_log_feature) {

if (isForced || ELASTICAPM_G(globals)->logger_->doesFeatureMeetsLevelCondition(static_cast<LogLevel>(level), static_cast<elasticapm::php::LogFeature>(feature))) {
if (lineNull) {
ELASTICAPM_G(globals)->logger_->printf(static_cast<LogLevel>(level), PRsv " " PRsv " " PRsv " " PRsv, PRcsvArg(category, categoryLength), PRcsvArg(file, fileLength), PRcsvArg(func, funcLength), PRcsvArg(message, messageLength));
ELASTICAPM_G(globals)->logger_->printf(static_cast<LogLevel>(level), "[" PRsv "] [" PRsv "] [" PRsv "] [" PRsv "] " PRsv, PRsvArg(elasticapm::php::getLogFeatureName(static_cast<elasticapm::php::LogFeature>(feature))), PRcsvArg(category, categoryLength), PRcsvArg(file, fileLength), PRcsvArg(func, funcLength), PRcsvArg(message, messageLength));
return;
}
ELASTICAPM_G(globals)->logger_->printf(static_cast<LogLevel>(level), PRsv " " PRsv " %d " PRsv " " PRsv, PRcsvArg(category, categoryLength), PRcsvArg(file, fileLength), line, PRcsvArg(func, funcLength), PRcsvArg(message, messageLength));
ELASTICAPM_G(globals)->logger_->printf(static_cast<LogLevel>(level), "[" PRsv "] [" PRsv "] [" PRsv ":%d] [" PRsv "] " PRsv, PRsvArg(elasticapm::php::getLogFeatureName(static_cast<elasticapm::php::LogFeature>(feature))), PRcsvArg(category, categoryLength), PRcsvArg(file, fileLength), line, PRcsvArg(func, funcLength), PRcsvArg(message, messageLength));
}
}
/* }}} */
Expand Down
4 changes: 4 additions & 0 deletions prod/native/libcommon/code/LogFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@ namespace elasticapm::php {
return feature.value();
}

[[nodiscard]] std::string_view getLogFeatureName(LogFeature feature) {
return magic_enum::enum_name(feature);
}

} // namespace elasticapm::php
1 change: 1 addition & 0 deletions prod/native/libcommon/code/LogFeature.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ enum LogFeature {
// clang-format on

[[nodiscard]] LogFeature parseLogFeature(std::string_view featureName);
[[nodiscard]] std::string_view getLogFeatureName(LogFeature feature);

} // namespace elasticapm::php
7 changes: 3 additions & 4 deletions prod/native/libcommon/code/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

namespace elasticapm::php {

using namespace std::string_literals;

void Logger::setLogFeatures(std::unordered_map<elasticapm::php::LogFeature, LogLevel> features) {
features_ = std::move(features);
}
Expand Down Expand Up @@ -78,8 +80,7 @@ void Logger::printf(LogLevel level, const char *format, ...) const {
auto msg = elasticapm::utils::stringVPrintf(format, args);
va_end(args);


std::string output;
std::string output = "[EDOT] "s;
output.append(getFormattedTime());
output.append(" ");

Expand Down Expand Up @@ -112,8 +113,6 @@ void Logger::printf(LogLevel level, const char *format, ...) const {
}
}



std::string Logger::getFormattedTime() const {
const auto now = std::chrono::system_clock::now();
const std::time_t nowTime = std::chrono::system_clock::to_time_t(now);
Expand Down
3 changes: 2 additions & 1 deletion prod/native/libcommon/code/LoggerInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "LogLevel.h"
#include "LogFeature.h"
#include "basic_macros.h"

#include <unordered_map>
#include <stdarg.h>
Expand All @@ -46,7 +47,7 @@ class LoggerInterface {

// clang-format off

#define ELOGF(logger, level, feature, format, ...) do { if (!logger || !logger->doesFeatureMeetsLevelCondition(level, elasticapm::php::LogFeature::feature)) break; logger->printf(level, format, ##__VA_ARGS__); } while(false);
#define ELOGF(logger, level, feature, format, ...) do { if (!logger || !logger->doesFeatureMeetsLevelCondition(level, elasticapm::php::LogFeature::feature)) break; logger->printf(level, "[" EL_STRINGIFY(feature) "] " format, ##__VA_ARGS__); } while(false);
#define ELOG(logger, level, format, ...) ELOGF(logger, level, ALL, format, ##__VA_ARGS__)

#define ELOGF_CRITICAL(logger, feature, format, ...) ELOGF(logger, LogLevel::logLevel_critical, feature, format, ##__VA_ARGS__)
Expand Down
6 changes: 3 additions & 3 deletions prod/native/libcommon/code/RequestScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class RequestScope {
}

void onRequestInit() {
ELOGF_DEBUG(log_, REQUEST, __FUNCTION__);
ELOGF_DEBUG(log_, REQUEST, "%s", __FUNCTION__);

resetRequest();

Expand Down Expand Up @@ -109,7 +109,7 @@ class RequestScope {
}

void onRequestShutdown() {
ELOGF_DEBUG(log_, REQUEST, __FUNCTION__);
ELOGF_DEBUG(log_, REQUEST, "%s", __FUNCTION__);

if (preloadDetected_) {
ELOGF_DEBUG(log_, REQUEST, "opcache.preload request detected on shutdown");
Expand All @@ -132,7 +132,7 @@ class RequestScope {
}

void onRequestPostDeactivate() {
ELOGF_DEBUG(log_, REQUEST, __FUNCTION__);
ELOGF_DEBUG(log_, REQUEST, "%s", __FUNCTION__);

resetRequest();

Expand Down
2 changes: 1 addition & 1 deletion prod/native/libcommon/test/LoggerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ TEST_F(LoggerTest, Formatting) {
ASSERT_NE(str.find("["s + std::to_string(getpid()) + "/"s), std::string::npos);
};
auto testFormattedTime = [](std::string_view str) {
ASSERT_EQ(str.length(), 32u);
ASSERT_EQ(str.length(), 39u);
ASSERT_TRUE(str.ends_with(" UTC]"sv));
};

Expand Down
28 changes: 21 additions & 7 deletions prod/php/ElasticOTel/Log/ElasticLogWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,31 @@

namespace Elastic\OTel\Log;

use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\SDK\Common\Configuration\Configuration;
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;

class ElasticLogWriter implements LogWriterInterface
{
private bool $attachLogContext;

public function __construct()
{
$this->attachLogContext = Configuration::getBoolean('ELASTIC_OTEL_LOG_OTEL_WITH_CONTEXT', true);
}

/**
* @param array<array-key, mixed> $context
*/
public function write(mixed $level, string $message, array $context): void
{
$edotLevel = is_string($level) ? Level::getFromPsrLevel($level) : Level::OFF;

$caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4)[3];

$func = ($caller['class'] ?? '') . ($caller['type'] ?? '') . $caller['function'];
$logContext = $this->attachLogContext ? (' context: ' . var_export($context, true)) : '';

/**
* elastic_otel_* functions are provided by the extension
*
Expand All @@ -42,12 +56,12 @@ public function write(mixed $level, string $message, array $context): void
\elastic_otel_log_feature( // @phpstan-ignore function.notFound
0 /* isForced */,
$edotLevel,
LogFeature::OTEL /* feature */,
'' /* category */,
'' /* file */,
0 /* line */,
$context['source'] ?? '' /* func */,
$message . ' context: ' . var_export($context, true) /* message */
LogFeature::OTEL,
'OpenTelemetry',
$caller['file'] ?? '',
$caller['line'] ?? '',
$func,
$message . $logContext
);
}

Expand Down