<commit_before>// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#ifdef ENABLE_LOGS_PREVIEW
#  include "opentelemetry/sdk/logs/logger.h"
#  include "opentelemetry/sdk/logs/log_record.h"
#  include "opentelemetry/sdk_config.h"
#  include "opentelemetry/trace/provider.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace logs
{
namespace trace_api = opentelemetry::trace;
namespace nostd     = opentelemetry::nostd;
namespace common    = opentelemetry::common;

Logger::Logger(nostd::string_view name,
               std::shared_ptr<LoggerContext> context,
               std::unique_ptr<instrumentationlibrary::InstrumentationLibrary>
                   instrumentation_library) noexcept
    : logger_name_(std::string(name)),
      instrumentation_library_(std::move(instrumentation_library)),
      context_(context)
{}

const nostd::string_view Logger::GetName() noexcept
{
  return logger_name_;
}

/**
 * Create and populate recordable with the log event's fields passed in.
 * The timestamp, severity, traceid, spanid, and traceflags, are injected
 * if the user does not specify them.
 */
void Logger::Log(opentelemetry::logs::Severity severity,
                 nostd::string_view name,
                 nostd::string_view body,
                 const common::KeyValueIterable &attributes,
                 trace_api::TraceId trace_id,
                 trace_api::SpanId span_id,
                 trace_api::TraceFlags trace_flags,
                 common::SystemTimestamp timestamp) noexcept
{
  // If this logger does not have a processor, no need to create a log record
  if (!context_)
  {
    return;
  }
  auto &processor = context_->GetProcessor();

  // TODO: Sampler (should include check for minSeverity)

  auto recordable = processor.MakeRecordable();
  if (recordable == nullptr)
  {
    OTEL_INTERNAL_LOG_ERROR("[LOGGER] Recordable creation failed");
    return;
  }

  // Populate recordable fields
  recordable->SetTimestamp(timestamp);
  recordable->SetSeverity(severity);
  recordable->SetName(name);
  recordable->SetBody(body);
  recordable->SetInstrumentationLibrary(GetInstrumentationLibrary());

  recordable->SetResource(context_->GetResource());

  attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept {
    recordable->SetAttribute(key, value);
    return true;
  });

  // Inject trace_id/span_id/trace_flags if none is set by user
  auto provider     = trace_api::Provider::GetTracerProvider();
  auto tracer       = provider->GetTracer(logger_name_);
  auto span_context = tracer->GetCurrentSpan()->GetContext();

  // Leave these fields in the recordable empty if neither the passed in values
  // nor the context values are valid (e.g. the application is not using traces)

  // TraceId
  if (trace_id.IsValid())
  {
    recordable->SetTraceId(trace_id);
  }
  else if (span_context.trace_id().IsValid())
  {
    recordable->SetTraceId(span_context.trace_id());
  }

  // SpanId
  if (span_id.IsValid())
  {
    recordable->SetSpanId(span_id);
  }
  else if (span_context.span_id().IsValid())
  {
    recordable->SetSpanId(span_id);
  }

  // TraceFlags
  if (trace_flags.IsSampled())
  {
    recordable->SetTraceFlags(trace_flags);
  }
  else if (span_context.trace_flags().IsSampled())
  {
    recordable->SetTraceFlags(span_context.trace_flags());
  }

  // Send the log record to the processor
  processor.OnReceive(std::move(recordable));
}

const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary &
Logger::GetInstrumentationLibrary() const noexcept<commit_msg>get span_id from context when Logger::Log received invalid span_id  (#1398)<commit_after>// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#ifdef ENABLE_LOGS_PREVIEW
#  include "opentelemetry/sdk/logs/logger.h"
#  include "opentelemetry/sdk/logs/log_record.h"
#  include "opentelemetry/sdk_config.h"
#  include "opentelemetry/trace/provider.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace logs
{
namespace trace_api = opentelemetry::trace;
namespace nostd     = opentelemetry::nostd;
namespace common    = opentelemetry::common;

Logger::Logger(nostd::string_view name,
               std::shared_ptr<LoggerContext> context,
               std::unique_ptr<instrumentationlibrary::InstrumentationLibrary>
                   instrumentation_library) noexcept
    : logger_name_(std::string(name)),
      instrumentation_library_(std::move(instrumentation_library)),
      context_(context)
{}

const nostd::string_view Logger::GetName() noexcept
{
  return logger_name_;
}

/**
 * Create and populate recordable with the log event's fields passed in.
 * The timestamp, severity, traceid, spanid, and traceflags, are injected
 * if the user does not specify them.
 */
void Logger::Log(opentelemetry::logs::Severity severity,
                 nostd::string_view name,
                 nostd::string_view body,
                 const common::KeyValueIterable &attributes,
                 trace_api::TraceId trace_id,
                 trace_api::SpanId span_id,
                 trace_api::TraceFlags trace_flags,
                 common::SystemTimestamp timestamp) noexcept
{
  // If this logger does not have a processor, no need to create a log record
  if (!context_)
  {
    return;
  }
  auto &processor = context_->GetProcessor();

  // TODO: Sampler (should include check for minSeverity)

  auto recordable = processor.MakeRecordable();
  if (recordable == nullptr)
  {
    OTEL_INTERNAL_LOG_ERROR("[LOGGER] Recordable creation failed");
    return;
  }

  // Populate recordable fields
  recordable->SetTimestamp(timestamp);
  recordable->SetSeverity(severity);
  recordable->SetName(name);
  recordable->SetBody(body);
  recordable->SetInstrumentationLibrary(GetInstrumentationLibrary());

  recordable->SetResource(context_->GetResource());

  attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept {
    recordable->SetAttribute(key, value);
    return true;
  });

  // Inject trace_id/span_id/trace_flags if none is set by user
  auto provider     = trace_api::Provider::GetTracerProvider();
  auto tracer       = provider->GetTracer(logger_name_);
  auto span_context = tracer->GetCurrentSpan()->GetContext();

  // Leave these fields in the recordable empty if neither the passed in values
  // nor the context values are valid (e.g. the application is not using traces)

  // TraceId
  if (trace_id.IsValid())
  {
    recordable->SetTraceId(trace_id);
  }
  else if (span_context.trace_id().IsValid())
  {
    recordable->SetTraceId(span_context.trace_id());
  }

  // SpanId
  if (span_id.IsValid())
  {
    recordable->SetSpanId(span_id);
  }
  else if (span_context.span_id().IsValid())
  {
    recordable->SetSpanId(span_context.span_id());
  }

  // TraceFlags
  if (trace_flags.IsSampled())
  {
    recordable->SetTraceFlags(trace_flags);
  }
  else if (span_context.trace_flags().IsSampled())
  {
    recordable->SetTraceFlags(span_context.trace_flags());
  }

  // Send the log record to the processor
  processor.OnReceive(std::move(recordable));
}

const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary &
Logger::GetInstrumentationLibrary() const noexcept
{'fraction_non_alphanumeric': 0.11021025147725712, 'fraction_numerical': 0.0010993541294489488, 'mean_word_length': 3.9175675675675676, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2094479', 'n_tokens_mistral': 2215, 'n_tokens_neox': 2176, 'n_words': 468}