图表注释
图表注释(Chart Annotations)是添加到图表上的标签或备注,用于提供额外的信息或上下文。注释帮助澄清图表中呈现的数据,帮助查看者理解关键点或趋势。在 Uptrace 中,您可以通过 API 创建注释,将部署事件、故障事件等时间线事件与指标和追踪数据的变化关联起来。
概述
图表注释的主要作用:
- 事件标记:标记部署、发布、故障等关键事件
- 时间关联:将时间线事件与指标变化关联,便于分析因果关系
- 团队协作:帮助团队成员理解图表中的异常点或趋势变化
- 问题排查:通过注释快速定位问题发生的时间点
注释显示方式
Uptrace 在图表上以方形点(square dots)的形式显示注释,位于 X 轴(时间轴)上。点击注释可以查看注释的描述和标签。描述字段支持 Markdown 格式,可以包含指向其他系统的链接,提供更多详细信息。
创建注释
您可以通过发送 HTTP POST 请求到 Uptrace API 来创建注释。
API 接口
端点:https://api.uptrace.dev/api/v1/annotations
方法:POST
请求头:
Content-Type: application/jsonuptrace-dsn: <YOUR_DSN>(必需)
请求体:JSON 格式
基本请求示例
使用 curl 创建注释:
curl -X POST https://api.uptrace.dev/api/v1/annotations \-H 'uptrace-dsn: <YOUR_DSN>' \-H 'Content-Type: application/json' \-d '{"name": "Deployed to production","attrs": {"service.version": "540d2ee"}}'
字段说明
注释的 JSON 请求体支持以下字段:
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
name | string | 是 | 注释名称,将显示在图表上 |
description | string | 否 | 注释描述文本,支持 Markdown 格式 |
color | string | 否 | 图表中使用的颜色,例如 green 或 #00ff00 |
attrs | object | 否 | 键值对元数据,例如 {"deployment.environment": "production"} |
fingerprint | string | 否 | 用于去重的唯一字符串。如果存在相同 fingerprint 的注释,Uptrace 会忽略其他注释 |
time | string | 否 | 覆盖注释时间,RFC3339 格式,例如 2024-01-15T10:30:00Z |
字段详细说明
name(注释名称)
注释名称是必需的字段,将显示在图表上。建议使用简洁、描述性的名称。
示例:
{"name": "Deployed to production","name": "v1.2.3 release","name": "Database migration completed"}
description(描述)
描述字段支持 Markdown 格式,可以包含链接、列表、代码块等。这对于提供更多上下文信息非常有用。
示例:
{"name": "Deployed to production","description": "Deployed version **v1.2.3** to production.\n\n- Fixed memory leak issue\n- Improved query performance\n\n[View release notes](https://github.com/example/releases/tag/v1.2.3)"}
color(颜色)
颜色字段用于指定注释在图表中显示的颜色。可以使用颜色名称(如 green、red、blue)或十六进制颜色代码(如 #00ff00、#ff0000)。
示例:
{"name": "Deployment","color": "green"}
{"name": "Incident","color": "#ff0000"}
attrs(属性)
属性字段是一个键值对对象,用于存储与注释相关的元数据。这些属性可以用于过滤和分组注释。
常用属性:
service.name:服务名称service.version:服务版本deployment.environment:部署环境deployment.name:部署名称
示例:
{"name": "Deployed to production","attrs": {"service.name": "api-service","service.version": "v1.2.3","deployment.environment": "production","deployment.name": "deploy-20240115"}}
fingerprint(指纹)
指纹字段用于去重。如果多个注释具有相同的 fingerprint,Uptrace 只会保留第一个,忽略后续的注释。这对于防止重复创建相同事件的注释非常有用。
示例:
{"name": "Deployed to production","fingerprint": "v1.2.3","attrs": {"service.version": "v1.2.3"}}
time(时间)
时间字段用于覆盖注释的时间戳。如果不提供,Uptrace 会使用当前时间。时间必须使用 RFC3339 格式。
示例:
{"name": "Deployed to production","time": "2024-01-15T10:30:00Z","attrs": {"service.version": "v1.2.3"}}
完整示例
创建一个完整的注释,包含所有字段:
curl -X POST https://api.uptrace.dev/api/v1/annotations \-H 'uptrace-dsn: <YOUR_DSN>' \-H 'Content-Type: application/json' \-d '{"name": "Deployed to production","description": "Deployed version **v1.2.3** to production environment.\n\n**Changes:**\n- Fixed memory leak in cache layer\n- Improved database query performance by 30%\n- Added new authentication endpoint\n\n[View full changelog](https://github.com/example/releases/tag/v1.2.3)","color": "green","fingerprint": "deploy-v1.2.3-prod","time": "2024-01-15T10:30:00Z","attrs": {"service.name": "api-service","service.version": "v1.2.3","deployment.environment": "production","deployment.name": "deploy-20240115","deployment.trigger": "manual"}}'
使用不同编程语言创建注释
Go 示例
package mainimport ("bytes""encoding/json""fmt""net/http""time")type Annotation struct {Name string `json:"name"`Description string `json:"description,omitempty"`Color string `json:"color,omitempty"`Attrs map[string]string `json:"attrs,omitempty"`Fingerprint string `json:"fingerprint,omitempty"`Time string `json:"time,omitempty"`}func createAnnotation(dsn string, annotation Annotation) error {url := "https://api.uptrace.dev/api/v1/annotations"jsonData, err := json.Marshal(annotation)if err != nil {return err}req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))if err != nil {return err}req.Header.Set("Content-Type", "application/json")req.Header.Set("uptrace-dsn", dsn)client := &http.Client{Timeout: 10 * time.Second}resp, err := client.Do(req)if err != nil {return err}defer resp.Body.Close()if resp.StatusCode != http.StatusOK {return fmt.Errorf("failed to create annotation: %s", resp.Status)}return nil}func main() {dsn := "https://your-token@api.uptrace.dev/your-project-id"annotation := Annotation{Name: "Deployed to production",Description: "Deployed version **v1.2.3** to production.",Color: "green",Fingerprint: "deploy-v1.2.3-prod",Time: time.Now().UTC().Format(time.RFC3339),Attrs: map[string]string{"service.name": "api-service","service.version": "v1.2.3","deployment.environment": "production",},}if err := createAnnotation(dsn, annotation); err != nil {fmt.Printf("Error: %v\n", err)} else {fmt.Println("Annotation created successfully")}}
Python 示例
import requestsimport jsonfrom datetime import datetimedef create_annotation(dsn, annotation):url = "https://api.uptrace.dev/api/v1/annotations"headers = {"Content-Type": "application/json","uptrace-dsn": dsn}response = requests.post(url, headers=headers, json=annotation)response.raise_for_status()return response.json()# 使用示例dsn = "https://your-token@api.uptrace.dev/your-project-id"annotation = {"name": "Deployed to production","description": "Deployed version **v1.2.3** to production.","color": "green","fingerprint": "deploy-v1.2.3-prod","time": datetime.utcnow().isoformat() + "Z","attrs": {"service.name": "api-service","service.version": "v1.2.3","deployment.environment": "production"}}try:result = create_annotation(dsn, annotation)print("Annotation created successfully:", result)except requests.exceptions.RequestException as e:print(f"Error creating annotation: {e}")
JavaScript/Node.js 示例
const https = require('https');function createAnnotation(dsn, annotation) {return new Promise((resolve, reject) => {const data = JSON.stringify(annotation);const options = {hostname: 'api.uptrace.dev',path: '/api/v1/annotations',method: 'POST',headers: {'Content-Type': 'application/json','Content-Length': data.length,'uptrace-dsn': dsn}};const req = https.request(options, (res) => {let responseData = '';res.on('data', (chunk) => {responseData += chunk;});res.on('end', () => {if (res.statusCode === 200) {resolve(JSON.parse(responseData));} else {reject(new Error(`Failed to create annotation: ${res.statusCode}`));}});});req.on('error', (error) => {reject(error);});req.write(data);req.end();});}// 使用示例const dsn = 'https://your-token@api.uptrace.dev/your-project-id';const annotation = {name: 'Deployed to production',description: 'Deployed version **v1.2.3** to production.',color: 'green',fingerprint: 'deploy-v1.2.3-prod',time: new Date().toISOString(),attrs: {'service.name': 'api-service','service.version': 'v1.2.3','deployment.environment': 'production'}};createAnnotation(dsn, annotation).then(result => {console.log('Annotation created successfully:', result);}).catch(error => {console.error('Error creating annotation:', error);});
使用场景
场景 1:CI/CD 集成
在 CI/CD 流水线中,在部署完成后自动创建注释:
#!/bin/bash# deploy.sh# 执行部署./deploy.sh# 部署成功后创建注释curl -X POST https://api.uptrace.dev/api/v1/annotations \-H "uptrace-dsn: $UPTRACE_DSN" \-H "Content-Type: application/json" \-d "{\"name\": \"Deployed $CI_COMMIT_SHORT_SHA\",\"description\": \"Deployed commit [$CI_COMMIT_SHORT_SHA]($CI_PROJECT_URL/-/commit/$CI_COMMIT_SHA) to $DEPLOYMENT_ENV\",\"color\": \"green\",\"fingerprint\": \"deploy-$CI_COMMIT_SHORT_SHA-$DEPLOYMENT_ENV\",\"attrs\": {\"service.version\": \"$CI_COMMIT_SHORT_SHA\",\"deployment.environment\": \"$DEPLOYMENT_ENV\",\"ci.pipeline.id\": \"$CI_PIPELINE_ID\"}}"
场景 2:版本发布标记
在发布新版本时创建注释:
curl -X POST https://api.uptrace.dev/api/v1/annotations \-H "uptrace-dsn: $UPTRACE_DSN" \-H "Content-Type: application/json" \-d "{\"name\": \"v1.2.3 Release\",\"description\": \"Released version **v1.2.3**\n\n**Highlights:**\n- Performance improvements\n- Bug fixes\n- New features\n\n[Release Notes](https://github.com/example/releases/tag/v1.2.3)\",\"color\": \"blue\",\"fingerprint\": \"release-v1.2.3\",\"attrs\": {\"release.version\": \"v1.2.3\",\"release.type\": \"minor\"}}"
场景 3:故障事件标注
在发生故障时创建注释,便于后续分析:
curl -X POST https://api.uptrace.dev/api/v1/annotations \-H "uptrace-dsn: $UPTRACE_DSN" \-H "Content-Type: application/json" \-d "{\"name\": \"Incident: Database Connection Pool Exhausted\",\"description\": \"**Incident Report**\n\n- **Time**: $(date -u +%Y-%m-%dT%H:%M:%SZ)\n- **Severity**: High\n- **Impact**: Service degradation\n- **Root Cause**: Database connection pool exhausted\n- **Resolution**: Increased pool size\n\n[Incident Details](https://incident.example.com/INC-123)\",\"color\": \"red\",\"fingerprint\": \"incident-db-pool-$(date +%Y%m%d)\",\"attrs\": {\"incident.id\": \"INC-123\",\"incident.severity\": \"high\",\"incident.type\": \"database\"}}"
场景 4:数据库迁移标记
在执行数据库迁移时创建注释:
curl -X POST https://api.uptrace.dev/api/v1/annotations \-H "uptrace-dsn: $UPTRACE_DSN" \-H "Content-Type: application/json" \-d "{\"name\": \"Database Migration: Add User Indexes\",\"description\": \"Executed database migration to add indexes on user table.\n\n**Migration ID**: 20240115001\n**Duration**: 45 seconds\n**Status**: Success\",\"color\": \"yellow\",\"fingerprint\": \"migration-20240115001\",\"attrs\": {\"migration.id\": \"20240115001\",\"migration.type\": \"schema\",\"migration.status\": \"success\"}}"
场景 5:配置变更标记
在修改配置时创建注释:
curl -X POST https://api.uptrace.dev/api/v1/annotations \-H "uptrace-dsn: $UPTRACE_DSN" \-H "Content-Type: application/json" \-d "{\"name\": \"Config Change: Increased Cache TTL\",\"description\": \"Updated cache TTL from 5 minutes to 15 minutes.\n\n**Reason**: Reduce database load\n**Changed By**: admin@example.com\",\"color\": \"orange\",\"attrs\": {\"config.change.type\": \"cache\",\"config.change.reason\": \"performance\"}}"
注释管理
查看注释
在 Uptrace 平台中查看注释:
- 登录 Uptrace 平台:https://uptrace.inner.youdao.com/
- 选择项目
- 导航到 "Metrics" 页面
- 打开任意图表
- 注释会显示在 X 轴上,点击注释可以查看详细信息
注释过滤
在查看图表时,可以使用注释的属性进行过滤:
- 按服务名称过滤:只显示特定服务的注释
- 按环境过滤:只显示特定环境的注释
- 按版本过滤:只显示特定版本的注释
注释去重
使用 fingerprint 字段可以防止创建重复的注释。如果多个注释具有相同的 fingerprint,Uptrace 只会保留第一个。
最佳实践:
- 为每个唯一事件使用唯一的 fingerprint
- 使用有意义的 fingerprint,例如:
deploy-v1.2.3-prod、incident-db-pool-20240115 - 避免使用随机字符串作为 fingerprint
最佳实践
1. 注释命名规范
建议使用统一的命名规范:
[事件类型]: [简短描述]
例如:
Deployment: v1.2.3 to productionIncident: Database connection pool exhaustedMigration: Add user indexesConfig Change: Increased cache TTL
2. 描述内容规范
描述应该包含:
- 事件概述:简要说明发生了什么
- 关键信息:版本号、时间、影响范围等
- 相关链接:指向更多详细信息的链接(如发布说明、故障报告)
3. 属性使用建议
合理使用属性字段:
- 必需属性:
service.name、service.version、deployment.environment - 可选属性:根据事件类型添加相关属性
- 避免过度使用:只添加有意义的属性,避免创建过多属性
4. 颜色使用建议
使用颜色来区分不同类型的事件:
- 绿色:成功事件(部署、发布)
- 红色:故障事件(故障、错误)
- 黄色:警告事件(迁移、配置变更)
- 蓝色:信息事件(版本发布、公告)
- 橙色:重要事件(性能问题、容量警告)
5. 时间戳管理
- 使用 UTC 时间:确保时间戳使用 UTC 时区
- 精确到秒:对于需要精确时间的事件,使用秒级精度
- 历史事件:使用
time字段为历史事件创建注释
6. 与告警集成
将注释与告警系统集成:
- 在告警触发时创建注释
- 在告警恢复时创建注释
- 使用注释标记故障的开始和结束时间
常见问题
1. 注释没有显示在图表上?
可能的原因:
- 检查时间范围:确认注释的时间在图表的时间范围内
- 检查属性过滤:如果图表使用了属性过滤,确认注释的属性匹配过滤条件
- 检查 DSN:确认使用的 DSN 正确,且属于当前项目
2. 如何删除注释?
Uptrace 目前不提供删除注释的 API。如果需要删除注释,请联系管理员或通过 UI 操作。
3. 如何批量创建注释?
可以通过脚本循环调用 API 来批量创建注释:
#!/bin/bashwhile IFS= read -r line; docurl -X POST https://api.uptrace.dev/api/v1/annotations \-H "uptrace-dsn: $UPTRACE_DSN" \-H "Content-Type: application/json" \-d "$line"done < annotations.json
4. 注释支持哪些 Markdown 语法?
注释的描述字段支持标准 Markdown 语法:
- 粗体:
**text** - 斜体:
*text* - 链接:
[text](url) - 列表:
- item或1. item - 代码:
`code` - 代码块:
```language\ncode\n```
5. 如何为历史事件创建注释?
使用 time 字段为历史事件创建注释:
{"name": "Historical Event","time": "2024-01-01T00:00:00Z","description": "This is a historical event"}
6. 注释会影响性能吗?
注释是轻量级的,不会影响性能。每个注释只存储少量元数据,不会影响指标查询或图表渲染性能。