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  }