github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/services/tracings/tracer.go (about) 1 /* 2 * Copyright 2023 Wang Min Xiang 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 */ 17 18 package tracings 19 20 import ( 21 "github.com/aacfactory/fns/commons/bytex" 22 "time" 23 ) 24 25 type Trace struct { 26 Id string 27 Span *Span 28 } 29 30 func New(id []byte) *Tracer { 31 return &Tracer{ 32 Id: bytex.ToString(id), 33 Span: nil, 34 current: nil, 35 } 36 } 37 38 type Tracer struct { 39 Id string 40 Span *Span 41 current *Span 42 } 43 44 func (trace *Tracer) Trace() (v *Trace) { 45 v = &Trace{ 46 Id: trace.Id, 47 Span: trace.Span, 48 } 49 return 50 } 51 52 func (trace *Tracer) Begin(pid []byte, endpoint []byte, fn []byte, tags ...string) { 53 if trace.current != nil && trace.current.Id == bytex.ToString(pid) { 54 return 55 } 56 current := &Span{ 57 Id: bytex.ToString(pid), 58 Endpoint: bytex.ToString(endpoint), 59 Fn: bytex.ToString(fn), 60 Begin: time.Now(), 61 Waited: time.Time{}, 62 End: time.Time{}, 63 Tags: make(map[string]string), 64 Children: nil, 65 parent: nil, 66 } 67 current.setTags(tags) 68 if trace.Span == nil { 69 trace.Span = current 70 trace.current = current 71 return 72 } 73 parent := trace.current 74 if parent.Children == nil { 75 parent.Children = make([]*Span, 0, 1) 76 } 77 parent.Children = append(parent.Children, current) 78 current.parent = parent 79 trace.current = current 80 } 81 82 func (trace *Tracer) Waited(tags ...string) { 83 if trace.current == nil { 84 return 85 } 86 trace.current.Waited = time.Now() 87 trace.current.setTags(tags) 88 return 89 } 90 91 func (trace *Tracer) Tagging(tags ...string) { 92 if trace.current == nil { 93 return 94 } 95 trace.current.setTags(tags) 96 return 97 } 98 99 func (trace *Tracer) Finish(tags ...string) { 100 if trace.current == nil { 101 return 102 } 103 if trace.current.Waited.IsZero() { 104 trace.current.Waited = trace.current.Begin 105 } 106 trace.current.End = time.Now() 107 trace.current.setTags(tags) 108 if trace.current.parent != nil { 109 trace.current = trace.current.parent 110 } 111 } 112 113 func (trace *Tracer) Mount(child *Span) { 114 if trace.current == nil { 115 return 116 } 117 if child == nil { 118 return 119 } 120 if trace.current.Children == nil { 121 trace.current.Children = make([]*Span, 0, 1) 122 } 123 child.parent = trace.current 124 child.mountChildrenParent() 125 trace.current.Children = append(trace.current.Children, child) 126 }