All skills
gogf avatar

/goframe-v2

@911705d
by GoFramegogf/skills81 stars
3

GoFrame v2 development skill. Use only when the target Go project uses or is explicitly adopting GoFrame v2: the nearest go.mod requires github.com/gogf/gf/v2, existing Go files import github.com/gogf/gf/v2 or any github.com/gogf/gf/v2/... component package, or the user asks to scaffold, migrate, or build with GoFrame. Trigger for GoFrame-backed Go work such as APIs/controllers/services, middleware, routing/config, ORM/DAO/DO/entity/database operations, gf CLI/codegen, HTTP/gRPC services, and microservice conventions. Do not trigger for generic Go projects without GoFrame evidence, frontend-only work, shell scripts, or unrelated infrastructure tasks.

Use this Skill: https://skilld.dev/gh/gogf/skills/goframe-v2

This session only. Nothing lands on disk.

references服务可观测性服务链路跟踪链路跟踪-背景知识.md

OpenTelemetry

分布式链路跟踪(Distributed Tracing)的概念最早是由 Google 提出来的,发展至今技术已经比较成熟,也是有一些协议标准可以参考。目前在 Tracing 技术这块比较有影响力的是两大开源技术框架:Netflix 公司开源的 OpenTracing 和 Google 开源的 OpenCensus。两大框架都拥有比较高的开发者群体。为形成统一的技术标准,两大框架最终磨合成立了 OpenTelemetry 项目,简称 otel。具体可以参考:

  1. OpenTracing介绍
  2. OpenTelemetry介绍

因此,我们的 Tracing 技术方案以 OpenTelemetry 为实施标准,协议标准的一些 Golang 实现开源项目:

  1. https://github.com/open-telemetry/opentelemetry-go
  2. https://github.com/open-telemetry/opentelemetry-go-contrib

其他第三方的框架和系统(如 Jaeger/Prometheus/Grafana 等)也会按照标准化的规范来对接 OpenTelemetry,使得系统的开发和维护成本大大降低。

重要概念

我们先看看 OpenTelemetry 的架构图,我们这里不会完整介绍,只会介绍其中大家常用的几个概念。 关于 OpenTelemetry 的内部技术架构设计介绍,可以参考 OpenTelemetry架构 , 关于语义约定请参考: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md

TracerProvider

主要负责创建 Tracer,一般是需要第三方的分布式链路跟踪管理平台提供具体的实现。默认情况是一个空的 TracerProvider (NoopTracerProvider),虽然也能创建 Tracer 但是内部其实不会执行具体的数据流传输逻辑。

Tracer

Tracer 是创建和管理 Span 的接口。一次完整的追踪链路(Trace)由一个或多个 Span 组成。下图示例表示了一个由 8 个 Span 组成的追踪链路:

        [Span A]  ←←←(the root span)
            |
     +------+------+
     |             |
 [Span B]      [Span C] ←←←(Span C is a `ChildOf` Span A)
     |             |
 [Span D]      +---+-------+
               |           |
           [Span E]    [Span F] >>> [Span G] >>> [Span H]
                                       ↑
                                       ↑
                                       ↑
                         (Span G `FollowsFrom` Span F)

时间轴的展现方式会更容易理解:

––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time

 [Span A···················································]
   [Span B··············································]
      [Span D··········································]
    [Span C········································]
         [Span E·······]        [Span F··] [Span G··] [Span H··]

我们通常通过以下方式创建一个 Tracer:

gtrace.NewTracer(tracerName)

Span

Span 是一条追踪链路中的基本组成要素,一个 Span 表示一个独立的工作单元,比如可以表示一次函数调用、一次 HTTP 请求等。Span 会记录如下基本要素:

  • 操作名称(Operation Name)
  • 服务的开始时间和结束时间
  • Attributes(属性,K/V 键值对形式)
  • Events(事件,K/V 键值对形式)
  • SpanContext(跨进程传播的上下文信息)

Span 是这么多对象中使用频率最高的,因此创建 Span 也非常简便,例如:

gtrace.NewSpan(ctx, spanName, opts...)

Attributes

Attributes 以 K/V 键值对的形式保存用户自定义标签,主要用于链路追踪结果的查询过滤。例如:http.method="GET", http.status_code=200。其中 key 值必须为字符串,value 必须是字符串、布尔型或者数值型。Span 中的 Attributes 仅自己可见,不会随着 SpanContext 传递给后续 Span。设置 Attributes 方式例如:

span.SetAttributes(
    label.String("http.remote", conn.RemoteAddr().String()),
    label.String("http.local", conn.LocalAddr().String()),
)

Events

Events 与 Attributes 类似,也是 K/V 键值对形式。与 Attributes 不同的是,Events 还会记录写入事件的时间戳,因此 Events 主要用于记录某些事件发生的时刻。Events 的 key 值同样必须为字符串,但对 value 类型则没有限制。例如:

span.AddEvent("http.request", trace.WithAttributes(
    label.Any("http.request.header", headers),
    label.Any("http.request.baggage", gtrace.GetBaggageMap(ctx)),
    label.String("http.request.body", bodyContent),
))

SpanContext

SpanContext 携带着一些用于**跨服务通信(跨进程)**的数据,主要包含:

  • 足够在系统中标识该 Span 的信息,比如:SpanId、TraceId。
  • Baggage - 为整条追踪链保存跨服务(跨进程)的 K/V 格式的用户自定义数据。Baggage 与 Attributes 类似,也是 K/V 键值对。与 Attributes 不同的是:
    • 其 key 和 value 都只能是字符串格式
    • Baggage 不仅当前 Span 可见,其会随着 SpanContext 传递给后续所有的子 Span。要小心谨慎地使用 Baggage - 因为在所有的 Span 中传递这些 K/V 会带来不小的网络和 CPU 开销。

Propagator

Propagator 传播器用于端对端的上下文数据编码/解码,例如:Client 到 Server 端的数据传输,TraceId、SpanId 和 Baggage 都需要通过传播器来管理数据传输。业务端开发者往往对 Propagator 无感知,只有中间件/拦截器的开发者需要了解它的作用。OpenTelemetry 的标准协议实现库提供了常用的 TextMapPropagator,用于常见的文本数据端到端传输。此外,为保证 TextMapPropagator 中的传输数据兼容性,不应当包含特殊字符,具体请参考:https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md

GoFrame 框架通过 gtrace 模块使用了以下传播器对象,并全局设置到了 OpenTelemetry 中:

// defaultTextMapPropagator is the default propagator for context propagation between peers.
defaultTextMapPropagator = propagation.NewCompositeTextMapPropagator(
    propagation.TraceContext{},
    propagation.Baggage{},
)

支持组件

:::tip GoFrame 的核心组件都已经全面支持 OpenTelemetry 标准,并且 自动开启 了链路跟踪特性,开发者无需显示调用、使用无感知。在没有注入外部 TracerProvider 的情况下,框架会使用默认的 TracerProvider,该 TracerProvider 只会自动创建 TraceID 及 SpanID,以便打通请求日志的链路,并不会执行复杂逻辑。 ::: 包括但不限于以下核心组件:

自动支持链路跟踪特性的组件 组件名 描述
HTTP Client gclient HTTP 客户端自动启用了链路跟踪特性,具体使用示例请参考后续示例章节。
HTTP Server ghttp HTTP 服务端自动启用了链路跟踪特性,具体使用示例请参考后续示例章节。
gRPC Client contrib/rpc/grpcx gRPC 客户端自动启用了链路跟踪特性,具体使用示例请参考后续示例章节。
gRPC Server contrib/rpc/grpcx gRPC 服务端自动启用了链路跟踪特性,具体使用示例请参考后续示例章节。
Logging glog 日志内容中需要注入当前请求的 TraceId,以便通过日志快速定位问题。该特性由 glog 组件实现,开发者在输出日志时需要调用 Ctx 链式操作方法将 context.Context 上下文变量传递到日志输出链路中。如果没有传递 context.Context 上下文变量,日志内容中将会丢失 TraceId。
ORM gdb 数据库的执行是很重要的链路环节,ORM 组件会将自身的执行情况记录到链路中,作为执行链路的一部分。
NoSQL Redis gredis Redis 的执行也是很重要的链路环节,Redis 组件会将自身的执行情况记录到链路中,作为执行链路的一部分。
Utils gtrace 对于 Tracing 特性的管理需要做一定的封装,主要考虑的是可扩展性和易用性两方面。该封装由 gtrace 模块实现,文档地址: https://pkg.go.dev/github.com/gogf/gf/v2/net/gtrace

参考资料

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk MEDIUM
  • Gen Agent Trust Hub16d

    The skill provides a comprehensive development guide and code examples for the GoFrame v2 framework. While highly informative for Go developers, it contains several examples with hardcoded placeholder secrets, tokens, and specific local file paths to sensitive configuration files (like Kubernetes credentials). These elements are provided for demonstration purposes but represent insecure practices if used in production without modification.

  • Socket16d

    5 alerts: gptSecurity, gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    227/949 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 911705d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 4 months ago.

Steadyupdated 4 months ago
  • Go
  • Database
  • goframe
  • orm
  • http
  • grpc
  • microservices
  • crud
  • scaffolding
  • middleware

README badge

README badge for gogf/skills

Provides instruction and conventions for developing with GoFrame v2, a modular Go framework for building HTTP and gRPC services, microservices, and database operations using its ORM, CLI tooling, and project scaffolding. Use this skill when the target project has GoFrame v2 as a dependency or when the user requests scaffolding, migrations, or service development with GoFrame conventions.

Generated from the current SKILL.md.

When should I use this skill?
Use this skill only when your Go project uses GoFrame v2, indicated by github.com/gogf/gf/v2 in go.mod or imports. Do not use for generic Go projects, frontend work, or infrastructure tasks unrelated to GoFrame.
Should I manually set created_at and updated_at fields?
No. GoFrame automatically writes created_at on insert and updated_at on insert/update/save. Manually setting these fields is redundant and violates project conventions.
What should I use for database operations instead of g.Map?
Always use DO objects from internal/model/do/. DO struct fields are interface{}, unset fields remain nil and are automatically ignored by the ORM.
How does soft delete work in GoFrame?
Call Delete() on the DAO; GoFrame automatically converts it to UPDATE SET deleted_at = NOW(). Queries automatically filter out soft-deleted rows without requiring manual WhereNull conditions.
Where should I implement business logic?
Implement business logic directly in the service/ directory. Do not use the logic/ directory unless explicitly requested.

Generated from the current SKILL.md. These answers refresh after source changes.