github.com/cloudwego/hertz@v0.9.3/internal/stats/tracer.go (about)

     1  /*
     2   * Copyright 2022 CloudWeGo Authors
     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  package stats
    18  
    19  import (
    20  	"context"
    21  	"runtime/debug"
    22  
    23  	"github.com/cloudwego/hertz/pkg/app"
    24  	"github.com/cloudwego/hertz/pkg/common/hlog"
    25  	"github.com/cloudwego/hertz/pkg/common/tracer"
    26  	"github.com/cloudwego/hertz/pkg/common/tracer/stats"
    27  )
    28  
    29  // Controller controls tracers.
    30  type Controller struct {
    31  	tracers []tracer.Tracer
    32  }
    33  
    34  // Append appends a new tracer to the controller.
    35  func (ctl *Controller) Append(col tracer.Tracer) {
    36  	ctl.tracers = append(ctl.tracers, col)
    37  }
    38  
    39  // DoStart starts the tracers.
    40  func (ctl *Controller) DoStart(ctx context.Context, c *app.RequestContext) context.Context {
    41  	defer ctl.tryRecover()
    42  	Record(c.GetTraceInfo(), stats.HTTPStart, nil)
    43  
    44  	for _, col := range ctl.tracers {
    45  		ctx = col.Start(ctx, c)
    46  	}
    47  	return ctx
    48  }
    49  
    50  // DoFinish calls the tracers in reversed order.
    51  func (ctl *Controller) DoFinish(ctx context.Context, c *app.RequestContext, err error) {
    52  	defer ctl.tryRecover()
    53  	Record(c.GetTraceInfo(), stats.HTTPFinish, err)
    54  	if err != nil {
    55  		c.GetTraceInfo().Stats().SetError(err)
    56  	}
    57  
    58  	// reverse the order
    59  	for i := len(ctl.tracers) - 1; i >= 0; i-- {
    60  		ctl.tracers[i].Finish(ctx, c)
    61  	}
    62  }
    63  
    64  func (ctl *Controller) HasTracer() bool {
    65  	return ctl != nil && len(ctl.tracers) > 0
    66  }
    67  
    68  func (ctl *Controller) tryRecover() {
    69  	if err := recover(); err != nil {
    70  		hlog.SystemLogger().Warnf("Panic happened during tracer call. This doesn't affect the http call, but may lead to lack of monitor data such as metrics and logs: %s, %s", err, string(debug.Stack()))
    71  	}
    72  }