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

package log // import "go.opentelemetry.io/otel/sdk/log"

import (
	
	
	

	
	
	
	
	
	
	
	semconv 
	
	
)

var now = time.Now

// Compile-time check logger implements log.Logger.
var _ log.Logger = (*logger)(nil)

type logger struct {
	embedded.Logger

	provider             *LoggerProvider
	instrumentationScope instrumentation.Scope

	selfObservabilityEnabled bool
	logCreatedMetric         otelconv.SDKLogCreated
}

func newLogger( *LoggerProvider,  instrumentation.Scope) *logger {
	 := &logger{
		provider:             ,
		instrumentationScope: ,
	}
	if !x.SelfObservability.Enabled() {
		return 
	}
	.selfObservabilityEnabled = true
	 := otel.GetMeterProvider()
	 := .Meter("go.opentelemetry.io/otel/sdk/log",
		metric.WithInstrumentationVersion(sdk.Version()),
		metric.WithSchemaURL(semconv.SchemaURL))

	var  error
	if .logCreatedMetric,  = otelconv.NewSDKLogCreated();  != nil {
		 = fmt.Errorf("failed to create log created metric: %w", )
		otel.Handle()
	}
	return 
}

func ( *logger) ( context.Context,  log.Record) {
	 := .newRecord(, )
	for ,  := range .provider.processors {
		if  := .OnEmit(, &);  != nil {
			otel.Handle()
		}
	}
}

// Enabled returns true if at least one Processor held by the LoggerProvider
// that created the logger will process param for the provided context and param.
//
// If it is not possible to definitively determine the param will be
// processed, true will be returned by default. A value of false will only be
// returned if it can be positively verified that no Processor will process.
func ( *logger) ( context.Context,  log.EnabledParameters) bool {
	 := EnabledParameters{
		InstrumentationScope: .instrumentationScope,
		Severity:             .Severity,
		EventName:            .EventName,
	}

	// If there are more Processors than FilterProcessors,
	// which means not all Processors are FilterProcessors,
	// we cannot be sure that all Processors will drop the record.
	// Therefore, return true.
	//
	// If all Processors are FilterProcessors, check if any is enabled.
	return len(.provider.processors) > len(.provider.fltrProcessors) || anyEnabled(, , .provider.fltrProcessors)
}

func anyEnabled( context.Context,  EnabledParameters,  []FilterProcessor) bool {
	for ,  := range  {
		if .Enabled(, ) {
			// At least one Processor will process the Record.
			return true
		}
	}
	// No Processor will process the record
	return false
}

func ( *logger) ( context.Context,  log.Record) Record {
	 := trace.SpanContextFromContext()

	 := Record{
		eventName:         .EventName(),
		timestamp:         .Timestamp(),
		observedTimestamp: .ObservedTimestamp(),
		severity:          .Severity(),
		severityText:      .SeverityText(),

		traceID:    .TraceID(),
		spanID:     .SpanID(),
		traceFlags: .TraceFlags(),

		resource:                  .provider.resource,
		scope:                     &.instrumentationScope,
		attributeValueLengthLimit: .provider.attributeValueLengthLimit,
		attributeCountLimit:       .provider.attributeCountLimit,
		allowDupKeys:              .provider.allowDupKeys,
	}
	if .selfObservabilityEnabled {
		.logCreatedMetric.Add(, 1)
	}

	// This ensures we deduplicate key-value collections in the log body
	.SetBody(.Body())

	// This field SHOULD be set once the event is observed by OpenTelemetry.
	if .observedTimestamp.IsZero() {
		.observedTimestamp = now()
	}

	.WalkAttributes(func( log.KeyValue) bool {
		.AddAttributes()
		return true
	})

	return 
}