Skip to content

Renovate/GitHub.com cloudfy azuremonitor 38432 #38450

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

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
10 changes: 10 additions & 0 deletions exporter/azuremonitorexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ Exception events are saved to the Application Insights `exception` table.
This exporter saves log records to Application Insights `traces` table.
[TraceId](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-traceid) is mapped to `operation_id` column and [SpanId](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-spanid) is mapped to `operation_parentId` column.

### Exceptions

This exporter saves exception records to Application Insights `exceptions` table when log records indicate an excetion [specification](https://opentelemetry.io/docs/specs/otel/trace/exceptions/).

Exceptions must be log records with `SeverityNumber` of 17 (Error) and the following attributes MUST be filled out:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls update based on current implementation


* exception.message
* exception.stacktrace
* exception.type

### Metrics

This exporter saves metrics to Application Insights `customMetrics` table.
Expand Down
95 changes: 76 additions & 19 deletions exporter/azuremonitorexporter/log_to_envelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"time"

"github.com/microsoft/ApplicationInsights-Go/appinsights/contracts"
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/traceutil"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/plog"
conventions "go.opentelemetry.io/collector/semconv/v1.12.0"
"go.uber.org/zap"

"github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/traceutil"
)

type logPacker struct {
Expand All @@ -25,31 +25,65 @@ func (packer *logPacker) LogRecordToEnvelope(logRecord plog.LogRecord, resource

data := contracts.NewData()

messageData := contracts.NewMessageData()
messageData.Properties = make(map[string]string)
logAttributeMap := logRecord.Attributes()

if hasRequiredKeys(logAttributeMap, conventions.AttributeExceptionMessage, conventions.AttributeExceptionType) {
// handle envelope for exceptions
exceptionData := contracts.NewExceptionData()
exceptionData.Properties = make(map[string]string)
exceptionData.SeverityLevel = packer.toAiSeverityLevel(logRecord.SeverityNumber())
exceptionData.ProblemId = logRecord.SeverityText()

exceptionDetails := mapIncomingAttributeMapExceptionDetail(logAttributeMap)
exceptionData.Exceptions = append(exceptionData.Exceptions, exceptionDetails)

envelope.Name = exceptionData.EnvelopeName("")

data.BaseData = exceptionData
data.BaseType = exceptionData.BaseType()
envelope.Data = data

envelope.Tags[contracts.OperationId] = traceutil.TraceIDToHexOrEmptyString(logRecord.TraceID())
envelope.Tags[contracts.OperationParentId] = traceutil.SpanIDToHexOrEmptyString(logRecord.SpanID())

resourceAttributes := resource.Attributes()
applyResourcesToDataProperties(exceptionData.Properties, resourceAttributes)
applyInstrumentationScopeValueToDataProperties(exceptionData.Properties, instrumentationScope)
applyCloudTagsToEnvelope(envelope, resourceAttributes)
applyInternalSdkVersionTagToEnvelope(envelope)

setAttributesAsProperties(logAttributeMap, exceptionData.Properties)

messageData.SeverityLevel = packer.toAiSeverityLevel(logRecord.SeverityNumber())
packer.sanitize(func() []string { return exceptionData.Sanitize() })

messageData.Message = logRecord.Body().AsString()
} else {
// handle envelope for messages (traces)
messageData := contracts.NewMessageData()
messageData.Properties = make(map[string]string)

envelope.Tags[contracts.OperationId] = traceutil.TraceIDToHexOrEmptyString(logRecord.TraceID())
envelope.Tags[contracts.OperationParentId] = traceutil.SpanIDToHexOrEmptyString(logRecord.SpanID())
messageData.SeverityLevel = packer.toAiSeverityLevel(logRecord.SeverityNumber())
messageData.Message = logRecord.Body().AsString()

envelope.Name = messageData.EnvelopeName("")
envelope.Name = messageData.EnvelopeName("")

data.BaseData = messageData
data.BaseType = messageData.BaseType()
envelope.Data = data
data.BaseData = messageData
data.BaseType = messageData.BaseType()
envelope.Data = data

resourceAttributes := resource.Attributes()
applyResourcesToDataProperties(messageData.Properties, resourceAttributes)
applyInstrumentationScopeValueToDataProperties(messageData.Properties, instrumentationScope)
applyCloudTagsToEnvelope(envelope, resourceAttributes)
applyInternalSdkVersionTagToEnvelope(envelope)
envelope.Tags[contracts.OperationId] = traceutil.TraceIDToHexOrEmptyString(logRecord.TraceID())
envelope.Tags[contracts.OperationParentId] = traceutil.SpanIDToHexOrEmptyString(logRecord.SpanID())

setAttributesAsProperties(logRecord.Attributes(), messageData.Properties)
resourceAttributes := resource.Attributes()
applyResourcesToDataProperties(messageData.Properties, resourceAttributes)
applyInstrumentationScopeValueToDataProperties(messageData.Properties, instrumentationScope)
applyCloudTagsToEnvelope(envelope, resourceAttributes)
applyInternalSdkVersionTagToEnvelope(envelope)

setAttributesAsProperties(logAttributeMap, messageData.Properties)

packer.sanitize(func() []string { return messageData.Sanitize() })
}

packer.sanitize(func() []string { return messageData.Sanitize() })
packer.sanitize(func() []string { return envelope.Sanitize() })
packer.sanitize(func() []string { return contracts.SanitizeTags(envelope.Tags) })

Expand Down Expand Up @@ -97,3 +131,26 @@ func timestampFromLogRecord(lr plog.LogRecord) pcommon.Timestamp {

return pcommon.NewTimestampFromTime(timeNow())
}

func mapIncomingAttributeMapExceptionDetail(attributemap pcommon.Map) *contracts.ExceptionDetails {
exceptionDetails := contracts.NewExceptionDetails()
if message, exists := attributemap.Get(conventions.AttributeExceptionMessage); exists {
exceptionDetails.Message = message.Str()
}
if typeName, exists := attributemap.Get(conventions.AttributeExceptionType); exists {
exceptionDetails.TypeName = typeName.Str()
}
if stackTrace, exists := attributemap.Get(conventions.AttributeExceptionStacktrace); exists {
exceptionDetails.Stack = stackTrace.Str()
}
return exceptionDetails
}
func hasRequiredKeys(attrMap pcommon.Map, keys ...string) bool {
for _, key := range keys {
_, exists := attrMap.Get(key)
if !exists {
return false
}
}
return true
}
Loading