github.com/kiali/kiali@v1.84.0/tracing/jaeger/model/converter/json/from_domain.go (about)

     1  // Copyright (c) 2019 The Jaeger Authors.
     2  // Copyright (c) 2017 Uber Technologies, Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  // http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  // Cloned from github.com/jaegertracing/jaeger/
    17  
    18  // nolint
    19  package json
    20  
    21  import (
    22  	"strings"
    23  
    24  	"github.com/kiali/kiali/log"
    25  	"github.com/kiali/kiali/tracing/jaeger/model"
    26  	"github.com/kiali/kiali/tracing/jaeger/model/json"
    27  )
    28  
    29  // FromDomain converts model.Trace into json.Trace format.
    30  // It assumes that the domain model is valid, namely that all enums
    31  // have valid values, so that it does not need to check for errors.
    32  func FromDomain(trace *model.Trace) *json.Trace {
    33  	fd := fromDomain{}
    34  	fd.convertKeyValuesFunc = fd.convertKeyValues
    35  	return fd.fromDomain(trace)
    36  }
    37  
    38  // FromDomainEmbedProcess converts model.Span into json.Span format.
    39  // This format includes a ParentSpanID and an embedded Process.
    40  func FromDomainEmbedProcess(span *model.Span) *json.Span {
    41  	fd := fromDomain{}
    42  	fd.convertKeyValuesFunc = fd.convertKeyValuesString
    43  	return fd.convertSpanEmbedProcess(span)
    44  }
    45  
    46  type fromDomain struct {
    47  	convertKeyValuesFunc func(keyValues model.KeyValues) []json.KeyValue
    48  }
    49  
    50  func (fd fromDomain) fromDomain(trace *model.Trace) *json.Trace {
    51  	jSpans := make([]json.Span, len(trace.Spans))
    52  	processes := &processHashtable{}
    53  	var traceID json.TraceID
    54  	for i, span := range trace.Spans {
    55  		if i == 0 {
    56  			traceId := model.TraceID{}
    57  			traceId.Unmarshal(span.TraceId)
    58  			traceID = json.TraceID(traceId.String())
    59  		}
    60  		processID := json.ProcessID(processes.getKey(span.Process))
    61  		jSpans[i] = fd.convertSpan(span, processID)
    62  	}
    63  	jTrace := &json.Trace{
    64  		TraceID:   traceID,
    65  		Spans:     jSpans,
    66  		Processes: fd.convertProcesses(processes.getMapping()),
    67  		Warnings:  trace.Warnings,
    68  	}
    69  	return jTrace
    70  }
    71  
    72  func (fd fromDomain) convertSpanInternal(span *model.Span) json.Span {
    73  	traceId := model.TraceID{}
    74  	traceId.Unmarshal(span.TraceId)
    75  	spanId, err := model.SpanIDFromBytes(span.SpanId)
    76  	if err != nil {
    77  		// On purpose to not propagate this error to the upper caller
    78  		log.Warningf("jaeger SpanId unmarshall error: %v", err)
    79  		spanId = 0
    80  	}
    81  	return json.Span{
    82  		TraceID:       json.TraceID(traceId.String()),
    83  		SpanID:        json.SpanID(spanId.String()),
    84  		Flags:         uint32(span.Flags),
    85  		OperationName: span.OperationName,
    86  		StartTime:     model.TimeAsEpochMicroseconds(span.StartTime.AsTime()),
    87  		Duration:      model.DurationAsMicroseconds(span.Duration.AsDuration()),
    88  		Tags:          fd.convertKeyValues(span.Tags),
    89  		Logs:          fd.convertLogs(span.Logs),
    90  	}
    91  }
    92  
    93  func (fd fromDomain) convertSpan(span *model.Span, processID json.ProcessID) json.Span {
    94  	s := fd.convertSpanInternal(span)
    95  	s.ProcessID = processID
    96  	s.Warnings = span.Warnings
    97  	s.References = fd.convertReferences(span)
    98  	return s
    99  }
   100  
   101  func (fd fromDomain) convertSpanEmbedProcess(span *model.Span) *json.Span {
   102  	s := fd.convertSpanInternal(span)
   103  	process := fd.convertProcess(span.Process)
   104  	s.Process = &process
   105  	s.References = fd.convertReferences(span)
   106  	return &s
   107  }
   108  
   109  func (fd fromDomain) convertReferences(span *model.Span) []json.Reference {
   110  	out := make([]json.Reference, 0, len(span.References))
   111  	for _, ref := range span.References {
   112  		traceId := model.TraceID{}
   113  		traceId.Unmarshal(ref.TraceId)
   114  		spanId, err := model.SpanIDFromBytes(ref.SpanId)
   115  		if err != nil {
   116  			// On purpose to not propagate this error to the upper caller
   117  			log.Warningf("jaeger SpanId unmarshall error: %v", err)
   118  			spanId = 0
   119  		}
   120  		out = append(out, json.Reference{
   121  			RefType: fd.convertRefType(ref.RefType),
   122  			TraceID: json.TraceID(traceId.String()),
   123  			SpanID:  json.SpanID(spanId.String()),
   124  		})
   125  	}
   126  	return out
   127  }
   128  
   129  func (fd fromDomain) convertRefType(refType model.SpanRefType) json.ReferenceType {
   130  	if refType == model.FollowsFrom {
   131  		return json.FollowsFrom
   132  	}
   133  	return json.ChildOf
   134  }
   135  
   136  func (fd fromDomain) convertKeyValues(keyValues model.KeyValues) []json.KeyValue {
   137  	out := make([]json.KeyValue, len(keyValues))
   138  	for i, kv := range keyValues {
   139  		var value interface{}
   140  		switch kv.VType {
   141  		case model.StringType:
   142  			value = kv.VStr
   143  		case model.BoolType:
   144  			value = kv.Bool()
   145  		case model.Int64Type:
   146  			value = kv.Int64()
   147  		case model.Float64Type:
   148  			value = kv.Float64()
   149  		case model.BinaryType:
   150  			value = kv.Binary()
   151  		}
   152  
   153  		out[i] = json.KeyValue{
   154  			Key:   kv.Key,
   155  			Type:  json.ValueType(strings.ToLower(kv.VType.String())),
   156  			Value: value,
   157  		}
   158  	}
   159  	return out
   160  }
   161  
   162  func (fd fromDomain) convertKeyValuesString(keyValues model.KeyValues) []json.KeyValue {
   163  	out := make([]json.KeyValue, len(keyValues))
   164  	for i, kv := range keyValues {
   165  		out[i] = json.KeyValue{
   166  			Key:   kv.Key,
   167  			Type:  json.ValueType(strings.ToLower(kv.VType.String())),
   168  			Value: kv.AsString(),
   169  		}
   170  	}
   171  	return out
   172  }
   173  
   174  func (fd fromDomain) convertLogs(logs []*model.Log) []json.Log {
   175  	out := make([]json.Log, len(logs))
   176  	for i, log := range logs {
   177  		out[i] = json.Log{
   178  			Timestamp: model.TimeAsEpochMicroseconds(log.Timestamp.AsTime()),
   179  			Fields:    fd.convertKeyValuesFunc(log.Fields),
   180  		}
   181  	}
   182  	return out
   183  }
   184  
   185  func (fd fromDomain) convertProcesses(processes map[string]*model.Process) map[json.ProcessID]json.Process {
   186  	out := make(map[json.ProcessID]json.Process)
   187  	for key, process := range processes {
   188  		out[json.ProcessID(key)] = fd.convertProcess(process)
   189  	}
   190  	return out
   191  }
   192  
   193  func (fd fromDomain) convertProcess(process *model.Process) json.Process {
   194  	return json.Process{
   195  		ServiceName: process.ServiceName,
   196  		Tags:        fd.convertKeyValuesFunc(process.Tags),
   197  	}
   198  }
   199  
   200  // DependenciesFromDomain converts []model.DependencyLink into []json.DependencyLink format.
   201  func DependenciesFromDomain(dependencyLinks []model.DependencyLink) []json.DependencyLink {
   202  	retMe := make([]json.DependencyLink, 0, len(dependencyLinks))
   203  	for _, dependencyLink := range dependencyLinks {
   204  		retMe = append(
   205  			retMe,
   206  			json.DependencyLink{
   207  				Parent:    dependencyLink.Parent,
   208  				Child:     dependencyLink.Child,
   209  				CallCount: dependencyLink.CallCount,
   210  			},
   211  		)
   212  	}
   213  	return retMe
   214  }