Opentelemetry SDK的简单用法

可观测性OpenTelemetry-Metrics(指标) 在介绍指标(Metrics)之前,我们先了解一下:什么是OpenTelemetry?微服务架构使开发人员能够更快地构建和发布软件,同时具有更大的独立性,因为他们不再受制于与单体架构相关的繁琐发布流程。随着这些现在分布式的系统的规模扩大,开发人员越来越难以看到他们自己的服务如何依赖或影响其他服务,特别是在部署期间或停机期间,速度和准确性至关重要。观测性使开发人员和操作员都能够获得对其系统的可见性。那么呢?为了使系统具有可观测性,必须进行仪表化。也就是说,代码必须发出跟踪、度量和日志。 阅读详情

Opentelemetry SDK的简单用法

概述

Opentelemetry trace的简单架构图如下,客户端和服务端都需要启动一个traceProvider,主要用于将trace数据传输到registry(如jaeger、opencensus等)。client和server通过context将整个链路串起来。

traceProvider会周期性的将数据推送到Registry,默认是5s

func NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorOption) SpanProcessor {
   ...
   o := BatchSpanProcessorOptions{
      BatchTimeout:       time.Duration(env.BatchSpanProcessorScheduleDelay(DefaultScheduleDelay)) * time.Millisecond,
      ExportTimeout:      time.Duration(env.BatchSpanProcessorExportTimeout(DefaultExportTimeout)) * time.Millisecond,
      MaxQueueSize:       maxQueueSize,
      MaxExportBatchSize: maxExportBatchSize,
   }
   ...
}

下面是官方提供的SDK,它实现了opentelemetry的API,也是操作opentelemetry所使用的基本库:

tracesdk "go.opentelemetry.io/otel/sdk/trace"

创建 TracerProvider

要使用trace,首先要创建一个TracerProvider,定义exporter以及相关属性。

使用 全局TracerProvider

参数表示应用名称或代码库名称

var tracer = otel.Tracer("app_or_package_name")

创建TracerProvider

下面展示了使用 Jaeger 作为exporter的tracerProvider,其中包含两个概念: exporter 和resource。前者为发送遥测数据的目的地,如jaeger、zepkin、opencensus等;后者通常用于添加非临时的底层元数据信息,如主机名,实例ID等。

// tracerProvider returns an OpenTelemetry TracerProvider configured to use
// the Jaeger exporter that will send spans to the provided url. The returned
// TracerProvider will also use a Resource configured with all the information
// about the application.
func tracerProvider(url string) (*tracesdk.TracerProvider, error) {
	// Create the Jaeger exporter
	exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
	if err != nil {
		return nil, err
	}
	tp := tracesdk.NewTracerProvider(
		// Always be sure to batch in production.
		tracesdk.WithBatcher(exp),
		// Record information about this application in a Resource.
		tracesdk.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String(service),
			attribute.String("environment", environment),
			attribute.Int64("ID", id),
		)),
	)
	return tp, nil
}

可以使用如下方式创建resource, semconv 包可以为资源属性提供规范化的名称。

// newResource returns a resource describing this application.
func newResource() *resource.Resource {
	r, _ := resource.Merge(
		resource.Default(),
		resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String("fib"),
			semconv.ServiceVersionKey.String("v0.1.0"),
			attribute.String("environment", "demo"),
		),
	)
	return r
}

注册tracerProvider

如果使用自定义的tracerProvider,需要将其注册为全局tracerProvider:

tp, err := tracerProvider("http://localhost:14268/api/traces")
	if err != nil {
		log.Fatal(err)
	}

	// Register our TracerProvider as the global so any imported
	// instrumentation in the future will default to using it.
	otel.SetTracerProvider(tp)

启动tracerProvider

tr := tp.Tracer("component-main")

	ctx, span := tr.Start(ctx, "foo")
	defer span.End()

关闭tracerProvider

当程序退出前,需要关闭tracerProvider,执行数据清理工作:

ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

    // Cleanly shutdown and flush telemetry when the application exits.
	defer func(ctx context.Context) {
		// Do not make the application hang when it is shutdown.
		ctx, cancel = context.WithTimeout(ctx, time.Second*5)
		defer cancel()
		if err := tp.Shutdown(ctx); err != nil {
			log.Fatal(err)
		}
	}(ctx)

span的简单用法

tracer会创建span,为了创建span,需要一个 context.Context 实例。该 context 通常来自于请求对象,或已经存在的父span。Go的 context 用于保存活动的span,当span启用后,就可以操作创建好的span以及其包含的已修改的上下文。当span结束后,其将成为不可变状态。

下面为从请求中获取span:

func httpHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := tracer.Start(r.Context(), "hello-span")
	defer span.End()

	// do some work to track with hello-span
}

获取当前span

// This context needs contain the active span you plan to extract.
ctx := context.TODO()
span := trace.SpanFromContext(ctx)

// Do something with the current span, optionally calling `span.End()` if you want it to en

创建嵌套的span

下面将 childSpan 嵌套在了 parentSpan 中,表示串行执行:

func parentFunction(ctx context.Context) {
	ctx, parentSpan := tracer.Start(ctx, "parent")
	defer parentSpan.End()

	// call the child function and start a nested span in there
	childFunction(ctx)

	// do more work - when this function ends, parentSpan will complete.
}

func childFunction(ctx context.Context) {
	// Create a span to track `childFunction()` - this is a nested span whose parent is `parentSpan`
	ctx, childSpan := tracer.Start(ctx, "child")
	defer childSpan.End()

	// do work here, when this function returns, childSpan will complete.
}

设置span相关的信息

添加属性

属性是一组key/value元数据,用于聚合、过滤以及对traces进行分组。

// setting attributes at creation...
ctx, span = tracer.Start(ctx, "attributesAtCreation", trace.WithAttributes(attribute.String("hello", "world")))
// ... and after creation
span.SetAttributes(attribute.Bool("isTrue", true), attribute.String("stringAttr", "hi!"))

可以使用如下方式预设置属性,然后再添加到span中:

var myKey = attribute.Key("myCoolAttribute")
span.SetAttributes(myKey.String("a value"))

注:trace的属性并不是随便定义的,它有一些特定的约束,参见 官方约定 以及 uptrace总结的约束

添加事件

事件为可读的消息,表示在span的生命周期中"发生了某些事情"。例如,假设某个函数需要获取锁来访问互斥的资源时,可以在两个节点创建事件,一个是尝试访问资源时,另一个是获取到锁时。如:

span.AddEvent("Acquiring lock")
mutex.Lock()
span.AddEvent("Got lock, doing work...")
// do stuff
span.AddEvent("Unlocking")
mutex.Unlock()

事件的一个有用的特点是,它们的时间戳显示为从span开始的偏移量(即事件发生的真实时间)。

事件也可以配置属性:

span.AddEvent("Cancelled wait due to external signal", trace.WithAttributes(attribute.Int("pid", 4328), attribute.String("signal", "SIGHUP")))

设置span状态

通常用于表示操作是否有异常。默认状态为 Unset ,可以手动将其设置为 Ok ,但通常没必要这么做。

result, err := operationThatCouldFail()
if err != nil {
	span.SetStatus(codes.Error, "operationThatCouldFail failed")
}

记录错误

用于记录错误日志或调用栈等信息。强烈建议在使用 RecordError 的同时,通过 SetStatus 将span状态设置为 Error :

result, err := operationThatCouldFail()
if err != nil {
	span.SetStatus(codes.Error, "operationThatCouldFail failed")
	span.RecordError(err)
}

完整代码

下面是对本地的一个函数 bar 生成trace信息:

func tracerProvider(url string) (*tracesdk.TracerProvider, error) {
	// Create the Jaeger exporter
	exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
	if err != nil {
		return nil, err
	}
	tp := tracesdk.NewTracerProvider(
		// Always be sure to batch in production.
		tracesdk.WithBatcher(exp),
		// Record information about this application in a Resource.
		tracesdk.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String(service),
			attribute.String("environment", environment),
			attribute.Int64("ID", id),
		)),
	)
	return tp, nil
}

func main() {
	tp, err := tracerProvider("http://localhost:14268/api/traces")
	if err != nil {
		log.Fatal(err)
	}

	// Register our TracerProvider as the global so any imported
	// instrumentation in the future will default to using it.
	otel.SetTracerProvider(tp)

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// Cleanly shutdown and flush telemetry when the application exits.
	defer func(ctx context.Context) {
		// Do not make the application hang when it is shutdown.
		ctx, cancel = context.WithTimeout(ctx, time.Second*5)
		defer cancel()
		if err := tp.Shutdown(ctx); err != nil {
			log.Fatal(err)
		}
	}(ctx)

	tr := tp.Tracer("component-main")

	ctx, span := tr.Start(ctx, "foo")
	defer span.End()

	bar(ctx)
}

func bar(ctx context.Context) {
	// Use the global TracerProvider.
	tr := otel.Tracer("component-bar")
	_, span := tr.Start(ctx, "bar")
	span.SetAttributes(attribute.Key("testset").String("value"))
	defer span.End()

	// Do bar...
}

Trace context的跨服务传播

为了跨服务传播Trace context需要注册一个propagator ,通常在创建注册TracerProvider之后执行。

func initTracer() (*sdktrace.TracerProvider, error) {
	// Create stdout exporter to be able to retrieve
	// the collected spans.
	exporter, err := stdout.New(stdout.WithPrettyPrint())
	if err != nil {
		return nil, err
	}

	// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces.
	// In a production application, use sdktrace.ProbabilitySampler with a desired probability.
	tp := sdktrace.NewTracerProvider(
		sdktrace.WithSampler(sdktrace.AlwaysSample()),
		sdktrace.WithBatcher(exporter),
	)
	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
	return tp, err
}

如上注册了两种propagator :TraceContext和Baggage,因此可以使用这两种数据结构传播上下文。

TraceContext

下面是 gorilla/mux 的服务端代码,通过 trace.SpanFromContext(r.Context()) 从请求的context构建span,当然也可以通过 tracer.Start(c.Context(), "getUser", oteltrace.WithAttributes(attribute.String("id", id))) 这种方式启动一个新的span:

func TestPropagationWithCustomPropagators(t *testing.T) {
	prop := propagation.TraceContext{}

	r := httptest.NewRequest("GET", "/user/123", nil)
	w := httptest.NewRecorder()

	ctx := trace.ContextWithRemoteSpanContext(context.Background(), sc)
	prop.Inject(ctx, propagation.HeaderCarrier(r.Header))

	var called bool
	router := mux.NewRouter()
	router.Use(Middleware("foobar", WithPropagators(prop)))
	router.HandleFunc("/user/{id}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		called = true
		span := trace.SpanFromContext(r.Context())
        defer span.End()
		assert.Equal(t, sc, span.SpanContext())
		w.WriteHeader(http.StatusOK)
	}))

	router.ServeHTTP(w, r)
	assert.True(t, called, "failed to run test")
}

baggage

下面是使用baggage的客户端和服务端代码,需要注意的是,客户端需要使用 otelhttp 。

客户端代码:

package main

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/baggage"
	stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
	"go.opentelemetry.io/otel/propagation"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
	"go.opentelemetry.io/otel/trace"
)

func initTracer() (*sdktrace.TracerProvider, error) {
	// Create stdout exporter to be able to retrieve
	// the collected spans.
	exporter, err := stdout.New(stdout.WithPrettyPrint())
	if err != nil {
		return nil, err
	}

	// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces.
	// In a production application, use sdktrace.ProbabilitySampler with a desired probability.
	tp := sdktrace.NewTracerProvider(
		sdktrace.WithSampler(sdktrace.AlwaysSample()),
		sdktrace.WithBatcher(exporter),
	)
	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
	return tp, err
}

func main() {
	tp, err := initTracer()
	if err != nil {
		log.Fatal(err)
	}
	defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			log.Printf("Error shutting down tracer provider: %v", err)
		}
	}()
	url := flag.String("server", "http://localhost:7777/hello", "server url")
	flag.Parse()

	client := http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)}

	bag, _ := baggage.Parse("username=donuts")
	ctx := baggage.ContextWithBaggage(context.Background(), bag)

	var body []byte

	tr := otel.Tracer("example/client")
	err = func(ctx context.Context) error {
		ctx, span := tr.Start(ctx, "say hello", trace.WithAttributes(semconv.PeerServiceKey.String("ExampleService")))
		defer span.End()
		req, _ := http.NewRequestWithContext(ctx, "GET", *url, nil)

		fmt.Printf("Sending request...\n")
		res, err := client.Do(req)
		if err != nil {
			panic(err)
		}
		body, err = ioutil.ReadAll(res.Body)
		_ = res.Body.Close()

		return err
	}(ctx)

	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Response Received: %s\n\n\n", body)
	fmt.Printf("Waiting for few seconds to export spans ...\n\n")
	time.Sleep(10 * time.Second)
	fmt.Printf("Inspect traces on stdout\n")
}

服务端代码:

package main

import (
	"context"
	"io"
	"log"
	"net/http"

	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/baggage"
	stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
	"go.opentelemetry.io/otel/trace"
)

func initTracer() (*sdktrace.TracerProvider, error) {
	// Create stdout exporter to be able to retrieve
	// the collected spans.
	exporter, err := stdout.New(stdout.WithPrettyPrint())
	if err != nil {
		return nil, err
	}

	// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces.
	// In a production application, use sdktrace.ProbabilitySampler with a desired probability.
	tp := sdktrace.NewTracerProvider(
		sdktrace.WithSampler(sdktrace.AlwaysSample()),
		sdktrace.WithBatcher(exporter),
		sdktrace.WithResource(resource.NewWithAttributes(semconv.SchemaURL, semconv.ServiceNameKey.String("ExampleService"))),
	)
	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
	return tp, err
}

func main() {
	tp, err := initTracer()
	if err != nil {
		log.Fatal(err)
	}
	defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			log.Printf("Error shutting down tracer provider: %v", err)
		}
	}()

	uk := attribute.Key("username")

	helloHandler := func(w http.ResponseWriter, req *http.Request) {
		ctx := req.Context()
		span := trace.SpanFromContext(ctx) // span为Hello
        defer span.End()
		bag := baggage.FromContext(ctx)
		span.AddEvent("handling this...", trace.WithAttributes(uk.String(bag.Member("username").Value())))

		_, _ = io.WriteString(w, "Hello, world!\n")
	}

    // otelhttp.NewHandler会在处理请求的同时创建一个名为Hello的span
	otelHandler := otelhttp.NewHandler(http.HandlerFunc(helloHandler), "Hello")

	http.Handle("/hello", otelHandler)
	err = http.ListenAndServe(":7777", nil)
	if err != nil {
		log.Fatal(err)
	}
}

上述代码生成的链路跟踪如下,client的 HTTP GET 会调用server端的 Hello 。Server的 Hello span是在处理请求时生成的,上述用的是 otelhttp ,其他registry也是类似的处理方式。

使用如下代码则可以启动两个独立的span,可以表示两个并行的任务:

helloHandler := func(w http.ResponseWriter, req *http.Request) {
		ctx := req.Context()
		ctx, span1 := tracer.Start(ctx, "span1 proecss", trace.WithLinks())
		defer span1.End()
		bag := baggage.FromContext(req.Context())
		span1.SetAttributes(attribute.String("span1", "test1"))
		span1.AddEvent("span1 handling this...", trace.WithAttributes(uk.String(bag.Member("username").Value())))

		ctx, span2 := tracer.Start(req.Context(), "span2 proecss", trace.WithLinks())
		defer span2.End()
		span2.SetAttributes(attribute.String("span2", "test2"))
		span2.AddEvent("span2 handling this...", trace.WithAttributes(uk.String(bag.Member("username").Value())))

		_, _ = io.WriteString(w, "Hello, world!\n")
	}

此外还可以通过 baggage.NewKeyValueProperty("key", "value") 等方式创建baggage。

注:baggage要遵循 W3C Baggage 规范 。

支持otel的工具

官方给出了很多 Registry ,如 Gorilla Mux 、 GORM 、 Gin-gonic 、 gRPC 等。更多可以参见 官方代码库 。

采样

provider := sdktrace.NewTracerProvider(
	sdktrace.WithSampler(sdktrace.AlwaysSample()),
)
.5

生产中可以考虑使用 TraceIDRatioBased 和 ParentBased 。

云原生内容分享(四):OpenTelemetry 重塑云原生的可观测性 随着云计算、微服务和容器化技术的快速发展,现代应用程序的架构变得越来越复杂。这种复杂性为运维人员和开发者带来了新的挑战,特别是在监控、追踪和诊断分布式系统的行为和性能方面。传统的监控工具和框架往往专注于单一的领域,如日志记录、度量收集或分布式追踪。然而,这些工具之间的互操作性和数据标准化程度有限,导致在大规模、多语言的云原生环境中实施全面可观测性变得困难且成本高昂。OpenTelemetry 与 Kubernetes 结合,构建了一套强大的云原生环境下的可观测性解决方案。 阅读详情

相关推荐

【可观测性系列】 Opentelemetry 介绍

大家好,我是蓝胖子,随着微服务的流行,服务的可观测性概念被越来越多人提及到,究竟什么是可观测性?我们应该如何构建服务的可观测性?我将会在这篇文章中逐步提及到,并对和可观测性相关的工具 Opentelemetry做一个大致的介绍。

我活在当下,我巨他妈勇敢。 1377

OpenTelemetry Java SDK 高级用法

通过引入 OpenTelemetry SDK,可以观测业务核心逻辑,比如给核心的业务设置一个 span 以统计、跟踪、分析其实际行为、设置业务属性指标等。此方法具有一定的侵入性。

BASK2311的博客 3833

(详细教程)opencv+pycharm+笔记本摄像头 做一个人脸识别

文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 一、安装opencv-python 这里推荐使用pycharm直接安装opencv-python 打开文件——设置——python解释器——点击+号 搜索opencv-python,点击安装包,等待片刻即可安装好 检查是否安装好,新建一个项目输入以下代码,若无报错则安装好 import cv2 二、准备分类器 咱们使用opencv官方提供的分类器,包括面部识别,侧...

qq_52852432的博客 1万+

使用 OpenTelemetry 和 Jaeger 使用 MinIO 进行分布式跟踪

几年前,当你有一个单体应用程序时,调试和诊断相当容易,因为可能只有一个服务有几个用户。如今,系统被分解为更小的微服务,这些微服务部署在 Kubernetes 之上的容器中,分布在不同云环境的多个集群中。在这些类型的分布式环境中,需要观察所有情况,包括整体情况,如果需要,还需要在更细粒度的级别上进行观察。可观察性大致可以分为三个子类别:日志记录、度量和跟踪。在这篇博文中,我们将向您展示在新的或现有的 MinIO 应用程序中设置跟踪是多么简单。我们将构建一个小型 MinIO 应用程序来执行一些基本请求;

分享身边生活经验blog 1434

AB脉冲详解(编码器,PLC,上位机)

编码器线有些是用不到的。Z脉冲:360度中,只有1度是输出,输出能力是。编码器实际就是发光二极管,所以电流超过20ma会缩短寿命或损坏。

cfqq1989的博客 1万+

爬虫君子协议-robots.txt协议

文章目录一.定义二.用法 一.定义 robots协议是一种约定俗称的爬虫协议,由网站主人规定了该网站的哪些内容可以爬取,哪些内容不可以爬取,擅自爬取可能承担相关法律责任。之所以称之为君子协议,是因为防君子不防小人,该协议并没有用技术手段实现反爬,只是一个申明。 在网站根目录后输入/robots.txt后即可查看该网站的君子协议 例如访问https://www.douban.com/robots.txt可查看豆瓣网站的君子协议 查看结果如下 User-agent: * Disallow: /subject_

Henrik-Yao的博客 7618

OpenTelemetry 链路追踪介绍

OpenTelemetry是一个合并了OpenTracing和OpenCensus的开源观测框架,本文简单介绍Open Telemetry。

2403_88275882的博客 1377

Windows上搭建OpenHarmony星闪开发环境:HiSpark Studio全流程指南

嵌入式开发中,环境搭建是项目启动的关键步骤。OpenHarmony作为开源操作系统,其构建体系依赖Python脚本和GN/Ninja工具链,对版本兼容性要求严格。星闪(NearLink)技术作为新一代短距无线通信方案,在时延、并发和抗干扰方面优势显著,广泛应用于智能家居、工业控制等场景。在Windows平台上,通过HiSpark Studio集成开发工具,开发者可高效完成代码编辑、编译、烧录与调试。然而,Python版本冲突、环境变量配置、驱动签名等问题常导致搭建失败。本文详细拆解从系统准备到编译验证的全流

weixin_32658257的博客 348

OpenTelemetry Java OTLP导出器深度解析:gRPC与HTTP传输协议对比

OpenTelemetry Java SDK提供了强大的可观测性解决方案,其中OTLP(OpenTelemetry Protocol)导出器是连接应用程序与可观测性后端的关键组件。本文将深入对比gRPC与HTTP两种传输协议在OTLP导出器中的实现差异、性能表现和适用场景,帮助开发者为不同应用环境选择最优方案。 ## 核心导出器实现概览 OpenTelemetry Java为三种可观测性信号(

gitblog_00180的博客 709

python指纹识别算法(亲测代码可用)

python指纹识别算法

2301_76482796的博客 3079

hpm6750evk2开发板(四)TCP回送(1000M网口)

再接下来我们修改代码,先找到配置网速的地方,肯定是在enet的初始化函数里面,我们一个函数一个函数找,也可以用单步调试一步一步找,结果发现是在enet_init函数里面调用的rtl8211_basic_mode_default_config函数配置网速的,我们把enet_phy_port_speed_100mbps改为enet_phy_port_speed_1000mbps,重新编译运行试试。首先我们复制一份lwip_tcpecho代码,重命名为lwip_tcpecho_RGMII,如下图所示。

Silas1750的博客 923

如何快速实现分布式大模型训练监控:OpenLLMetry完整集成指南

OpenLLMetry是一款基于OpenTelemetry的开源可观测性工具,专为大模型(LLM)应用打造。它提供了全面的监控能力,帮助开发者追踪、分析和优化分布式大模型训练过程,确保系统稳定运行并提升模型性能。 [![OpenLLMetry标志](https://raw.gitcode.com/gh_mirrors/op/openllmetry/raw/4af91cc912702a05ba9b

gitblog_01058的博客 1145

30分钟用 Restful ABAP Programming(RAP)模型开发一个支持增删改查的 Fiori 应用

2016年时,Jerry曾经写过一系列关于SAP Fiori Smart Template(现在更名为Fiori Elements了)的博客,介绍了所谓的MDD开发方法论 - Metadata Driven Development,即通过开发维护了对应annotation(注解)的CDS view,结合SAP WebIDE,能够花费最少的编程代价,就能够在短时间内获得一个支持增删改查的Fiori应......

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 5955

OpenLIT 开源项目教程

OpenLIT 是一个 OpenTelemetry 原生工具,旨在帮助开发者深入了解其大型语言模型(LLM)应用程序在生产环境中的性能。它自动收集 LLM 的输入和输出元数据,并监控自托管 LLM 的 GPU 性能。OpenLIT 通过简单的集成,使得在生成式人工智能(GenAI)项目中实现可观察性变得轻松。 ## 项目快速启动 ### 步骤 1: 部署 OpenLIT 堆栈 首先,克隆 Ope

gitblog_00321的博客 712

如何设置反馈点

前面的POWER DC仿真都是忽略反馈线进行的仿真,如果单板压降不过,电源会自动调整输出电压,来满足负载的得到额定的电压.可以看到因为设置了反馈点,源端电压就被抬高到满足压降的值了。仿真上也可以自己添加反馈点,以得到抬高后的电源输出电压值。同样以下图的CPU的Core电源为例。按照流程正常设置好参数。

weixin_54787054的博客 1148

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

学习使用Opentelemetry python SDK

OpenTelemetry 由 OpenTracing 和OpenCensus项目合并而成,是一组规范、工具、API 和 SDK 的集合。使用它来检测、生成、收集和导出遥测数据(Metrics、Logs 和 Traces),以帮助运维开发人员分析软件的性能和行为。为众多开发人员带来 Metrics、Traces、Logs 的统一标准,三者都有相同的元数据结构,可以轻松实现互相关联。OpenTelemetry 是一个CNCF 孵化项目。

程序源的博客 4292

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Elastic 现在提供 OpenTelemetry SDK 的发行版

OpenTelemetry 是一个厂商中立的可观测性框架和工具包,支持在应用程序和分布式微服务架构中的跟踪、指标和日志等遥测信号。OpenTelemetry 是由一系列标准推动的,旨在提供一致的方法来监测和观察应用程序行为。OpenTelemetry 是在云原生计算基金会(CNCF)的保护伞下孵化的项目,目前是第二活跃的项目,仅次于 Kubernetes。你可以在OpenTelemetry 网站上阅读更多关于采用 OpenTelemetry 的概念、术语和技术的内容。

Elastic 中国社区官方博客 1389

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

不加载PHP OpenTelemetry SDK实现Trace‌与Logs

前面两篇我们分别介绍了OpenTelemetry原理以及借助PHP OpenTelemetry SDK实现的分布式链路追踪Trace‌和日志Logs,按理说我们已经可以起飞了✈️。但是实际情况可能各有不同,有些PHP项目使用的PHP版本相对老旧,而且由于历史的原因升级是一件很麻烦的事。那怎么办呢?不能升级PHP版本就无法使用SDK且无法实现自己项目的OpenTelemetry 布式链路追踪Trace‌和日志Logs?答案当然是:❌。

小马过河R的博客 1591

Temporal Go SDK samples监控与追踪:OpenTelemetry集成指南

Temporal Go SDK samples提供了丰富的分布式工作流示例,而有效的监控与追踪是保障工作流稳定运行的关键。本文将详细介绍如何在Temporal Go SDK samples中集成OpenTelemetry,实现对工作流的全面监控与追踪,帮助开发者快速定位问题、优化性能。 ## OpenTelemetry在Temporal工作流中的价值 OpenTelemetry作为云原生领域的

gitblog_00700的博客 1046

OpenTelemetry-go的SDK使用方法

2019年5月,OpenCensus 和 OpenTracing形成了 OpenTelemetry(简称 OTel)也就是说,我们在使用链路追踪SDK的时候就需要使用OpenTelemetry的新规范.OpenTelemetry帮我们实现了相应语言的SDK,所以我们只需要进行调用即可.接下来,我们开始对go所对应的SDK进行使用.本文主要根据官方文档实例进行讲解.

a1023934860的博客 3966

OpenTelemetry系列 - 第2篇 Java端接入OpenTelemetry

目录一、架构说明二、方式1 - 自动化2.1 opentelemetry-javaagent.jar(Java8+ )2.2 使用opentelemetry-javaagent.jar完成自动注入2.3 配置opentelemetry-javaagent.jar2.4 使用注解(@WithSpan, @SpanAttribute)2.5.1 代码集成@WithSpan, @SpanAttribute2.5.2 禁用已标注@WithSpan的方法的自动注入:2.5.3 不修改代码的情况下启用@WithSpan

罗小爬的技术宝书 9467

Opentelemetry简介

目录简介为什么使用Opentelemetry数据类型TracingMetricsLoggingBaggage包含哪些内容跨语言的规范CollectorReceiverProcessorExporter客户端参考 简介 OpenTelemetry 是一组 API、SDK、工具和集成,旨在创建和管理遥测数据,例如Trace、Metrics和Logs。该项目提供了一个与供应商无关的实现,可以将其配置为将遥测数据发送到您选择的后端。它支持各种流行的开源项目,包括 Jaeger 和 Prometheus。 主要解决的

qq_27749613的博客 1万+

opentelemetry笔记

OpenTelemetry C++ 项目通过模块化设计,将接口、实现和导出器分离,提供了高效、灵活的分布式追踪和指标采集方案。它的架构保证了可扩展性,允许用户根据需求配置或扩展功能。如果需要更深入的说明,可以指定某个模块或文件!OpenTelemetry C++ 项目的架构体现了模块化、灵活性和高性能的特点。这种设计值得学习,特别是在开发分布式系统、异步处理和可扩展性框架时,可以借鉴其 API/SDK 分离、可插拔设计和高效的并发处理等技术思想。

fuyouzhiyi的博客 1711
上一篇: “不敢去怀疑代码,又不得不怀疑代码”记一次网络请求超时分析
下一篇: Redis主从复制-Redis学习
JavaMonsterr
博客等级 码龄4年 211粉丝 481原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值