| // Licensed to Apache Software Foundation (ASF) under one or more contributor |
| // license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright |
| // ownership. Apache Software Foundation (ASF) licenses this file to you under |
| // the Apache License, Version 2.0 (the "License"); you may |
| // not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| package core |
| |
| import ( |
| "fmt" |
| "reflect" |
| "time" |
| |
| "github.com/apache/skywalking-go/plugins/core/operator" |
| |
| commonv3 "github.com/apache/skywalking-go/protocols/collect/common/v3" |
| logv3 "github.com/apache/skywalking-go/protocols/collect/logging/v3" |
| ) |
| |
| func (t *Tracer) LogReporter() interface{} { |
| return t |
| } |
| |
| type logTracingContext interface { |
| GetServiceName() string |
| GetInstanceName() string |
| GetTraceID() string |
| GetTraceSegmentID() string |
| GetSpanID() int32 |
| GetEndPointName() string |
| } |
| |
| var noopContext = &NoopSpan{} |
| |
| func (t *Tracer) ReportLog(ctx, timeObj interface{}, level, msg string, labels map[string]string) { |
| tracingContext, ok := ctx.(logTracingContext) |
| if !ok || tracingContext == nil { |
| return |
| } |
| entity := t.ServiceEntity |
| if entity == nil { |
| return |
| } |
| timeData, ok := timeObj.(time.Time) |
| if !ok { |
| // as a fallback strategy to solve some plugins that |
| // cannot be introduced into the standard library |
| timeData = time.Now() |
| } |
| |
| tags := &logv3.LogTags{ |
| Data: []*commonv3.KeyStringValuePair{ |
| { |
| Key: "LEVEL", |
| Value: level, |
| }, |
| }, |
| } |
| for k, v := range labels { |
| tags.Data = append(tags.Data, &commonv3.KeyStringValuePair{ |
| Key: k, |
| Value: v, |
| }) |
| } |
| logData := &logv3.LogData{ |
| Timestamp: Millisecond(timeData), |
| Service: tracingContext.GetServiceName(), |
| ServiceInstance: tracingContext.GetInstanceName(), |
| Endpoint: tracingContext.GetEndPointName(), |
| Body: &logv3.LogDataBody{ |
| Type: "TEXT", |
| Content: &logv3.LogDataBody_Text{ |
| Text: &logv3.TextLog{Text: msg}, |
| }, |
| }, |
| TraceContext: &logv3.TraceContext{ |
| TraceId: tracingContext.GetTraceID(), |
| TraceSegmentId: tracingContext.GetTraceSegmentID(), |
| SpanId: tracingContext.GetSpanID(), |
| }, |
| Tags: tags, |
| Layer: "GENERAL", |
| } |
| |
| t.Reporter.SendLog(logData) |
| } |
| |
| func (t *Tracer) GetLogContext(withEndpoint bool) interface{} { |
| var ( |
| serviceName string |
| instanceName string |
| endpoint string |
| |
| activeSpan TracingSpan = noopContext |
| ) |
| |
| if s, ok := t.ActiveSpan().(TracingSpan); ok && s != nil { |
| activeSpan = s |
| if withEndpoint { |
| endpoint = findEndpointNameBySpan(s) |
| } |
| } |
| entity := t.Entity() |
| if e, ok := entity.(operator.Entity); ok && e != nil && !reflect.ValueOf(e).IsNil() { |
| serviceName, instanceName = e.GetServiceName(), e.GetInstanceName() |
| } |
| return &SkyWalkingLogContext{ |
| ServiceName: serviceName, |
| InstanceName: instanceName, |
| TraceID: activeSpan.GetTraceID(), |
| TraceSegmentID: activeSpan.GetSegmentID(), |
| SpanID: activeSpan.GetSpanID(), |
| EndPoint: endpoint, |
| } |
| } |
| |
| func findEndpointNameBySpan(s TracingSpan) string { |
| tmp := s |
| for tmp != nil { |
| if name := tmp.GetOperationName(); name != "" { |
| return name |
| } |
| tmp = tmp.ParentSpan() |
| } |
| return "" |
| } |
| |
| type SkyWalkingLogContext struct { |
| ServiceName string |
| InstanceName string |
| TraceID string |
| EndPoint string |
| TraceSegmentID string |
| SpanID int32 |
| } |
| |
| func (s *SkyWalkingLogContext) GetServiceName() string { |
| return s.ServiceName |
| } |
| |
| func (s *SkyWalkingLogContext) GetInstanceName() string { |
| return s.InstanceName |
| } |
| |
| func (s *SkyWalkingLogContext) GetTraceID() string { |
| return s.TraceID |
| } |
| |
| func (s *SkyWalkingLogContext) GetTraceSegmentID() string { |
| return s.TraceSegmentID |
| } |
| |
| func (s *SkyWalkingLogContext) GetSpanID() int32 { |
| return s.SpanID |
| } |
| |
| func (s *SkyWalkingLogContext) GetEndPointName() string { |
| return s.EndPoint |
| } |
| |
| func (s *SkyWalkingLogContext) String() string { |
| return fmt.Sprintf("[%s,%s,%s,%s,%d]", s.ServiceName, s.InstanceName, |
| s.TraceID, s.TraceSegmentID, s.SpanID) |
| } |