golang之增加版本信息功能
在实际开发中,当开发完一个 apiserver 特性后,会编译 apiserver 二进制文件并发布到生产环境,很多时候为了定位问题和出于安全目的(不能发错版本),我们需要知道当前 apiserver 的版本,以及一些编译时候的信息,如编译时 Go 的版本、Git 目录是否 clean,以及基于哪个 git commmit 来编译的。在一个编译好的可执行程序中,我们通常可以用类似 ./app_name -v 的方式来获取版本信息。
我们可以将这些信息写在配置文件中,程序运行时从配置文件中取得这些信息进行显示。但是在部署程序时,除了二进制文件还需要额外的配置文件,不是很方便。或者将这些信息写入代码中,这样不需要额外的配置,但要在每次编译时修改代码文件,也比较麻烦。Go 官方提供了一种更好的方式:通过 -ldflags -X importpath.name=value(详见 -ldflags -X importpath.name=value)来给程序自动添加版本信息。
1.增加参数-v
package main import (
"encoding/json"
"fmt"
"os"
...
v "apiserver/pkg/version"
...
) var (
version = pflag.BoolP("version", "v", false, "show version info.")
) func main() {
pflag.Parse()
if *version {
v := v.Get()
marshalled, err := json.MarshalIndent(&v, "", " ")
if err != nil {
fmt.Printf("%v\n", err)
os.Exit(1)
} fmt.Println(string(marshalled))
return
}
...
}
pkg/version包中的实现:
base.go
package version // 变量通过-ldflags -X importpath.name=value在编译时传入程序中
var (
gitTag = "" //
gitBranch = ""
gitCommit = "$Format:%H$"
gitTreeState = "not a git tree"
buildDate = "1970-01-01T00:00:00Z"
)
version.go
package version import (
"fmt"
"runtime"
) type Info struct {
GitTag string `json:"gitTag"`
GitBranch string `json:"gitBranch"`
GitCommit string `json:"gitCommit"`
GitTreeState string `json:"gitTreeState"`
BuildDate string `json:"buildDate"`
GoVersion string `json:"goVersion"`
Compiler string `json:"compiler"`
Platform string `json:"platform"`
} func (info Info) String() string {
return info.GitTag
} func Get() Info {
return Info{
GitTag: gitTag,
GitBranch: gitBranch,
GitCommit: gitCommit,
GitTreeState: gitTreeState,
BuildDate: buildDate,
GoVersion: runtime.Version(),
Compiler: runtime.Compiler,
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
}
}
其中的gitTag, gitBranch,gitComit,gitTreeState,buildDate信息都是在build的时候, 使用-ldflags -X key=value的方式指定参数
Makefile文件中:
.PHONY: all build windows mac run tidy check cert test cover lint docker clean help BIN_FILE=golang-demo
MAIN_FILE=./cmd/app/main.go SHELL := /bin/bash
BASEDIR = $(shell pwd) # build with verison infos
versionDir = "golang-demo/pkg/version"
## 获取仓库tag
gitTag = $(shell if [ "`git describe --tags --abbrev=0 2>/dev/null`" != "" ];then git describe --tags --abbrev=0; else git log --pretty=format:'%h' -n 1; fi)
buildDate = $(shell TZ=Asia/Shanghai date +%FT%T%z)
gitCommit = $(shell git log --pretty=format:'%H' -n 1)
gitTreeState = $(shell if git status|grep -q 'clean';then echo clean; else echo dirty; fi)
gitBranch = $(shell git rev-parse --abbrev-ref HEAD) ldflags="-w -X ${versionDir}.gitTag=${gitTag} -X ${versionDir}.buildDate=${buildDate} -X ${versionDir}.gitBranch=${gitBranch} -X ${versionDir}.gitCommit=${gitCommit} -X ${versionDir}.gitTreeState=${gitTreeState}" # 默认执行
all: build # 打包成二进制文件
build: tidy check
@CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -ldflags $(ldflags) -o $(BIN_FILE)_linux $(MAIN_FILE) windows: tidy check
@CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -v -ldflags "-w -s" -o $(BIN_FILE)_windows.exe $(MAIN_FILE) mac: tidy check
@CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -v -ldflags "-w -s" -o $(BIN_FILE)_darwin $(MAIN_FILE) # 启动服务
run:
@go run $(MAIN_FILE) -c ./config/config.yaml tidy:
@go mod tidy # 代码验证
check:
@gofmt -s -w ./
@go vet $(MAIN_FILE) cert:
@openssl req -new -nodes -x509 -out config/server.crt -keyout config/server.key -days 3650 -subj "/C=DE/ST=NRW/L=Earth/O=Random Company/OU=IT/CN=127.0.0.1/emailAddress=xxxxx@qq.com" # 单元测试
test:
@go test ./... # 覆盖测试
cover:
@go test -coverprofile xx.out
@go tool cover -html=xx.out lint:
@golangci-lint run --enable-all docker:
@docker build -t golang-demo:latest . clean:
@go clean -x
rm -f "xx.out" help:
@echo "make - 格式化go代码 并编译生成二进制文件"
@echo "make test - 执行测试case"
@echo "make check - 代码检查"
@echo "make cover - 检测测试覆盖率"
@echo "make run - 启动服务"
@echo "make lint - 执行代码检查"
@echo "make docker - 生成Docker镜像"
@echo "make clean - 清理中间目标文件"
@echo "make build - 编译成二进制文件(默认:Linux)"
@echo "make windows - 编译成二进制文件(Windows)"
@echo "make mac - 编译成二进制文件(Mac)" # include ./TestMakefile 包含其他Makefile
-w: 去除调试信息, 无法使用gdb调试, 但是二进制文件更小
执行./golang-demo -v
{
"gitTag": "d62a870",
"gitBranch": "master",
"gitCommit": "d62a87056066b2f8ecf6caf64b3bd1d80d60a5e1",
"gitTreeState": "dirty",
"buildDate": "2023-08-24T17:10:45+0800",
"goVersion": "go1.20.7",
"compiler": "gc",
"platform": "linux/amd64"
}
golang之增加版本信息功能的更多相关文章
- webpack 打包增加版本信息
What do we need? 笔者目的是在vue项目打包后的 dist/index.html 文件中写入本次打包git用户.最后一次git提交信息,这样做的目的是便于线上项目的管理和防止同事之间的 ...
- GetFileVersionInfoSize函数确定操作系统是否可以检索指定文件的版本信息
GetFileVersionInfoSize函数 -------------------------------------------------- ------------------------ ...
- java在线聊天项目0.3版本 制作客户端窗体,实现发送按钮和回车发送信息功能,使用ActionListener监听事件中actionPerformed方法(用内部类和匿名内部类两种方法)
方法一,使用匿名内部类的监听方法,因方法一致代码稍冗余 package com.swift; import java.awt.BorderLayout; import java.awt.Color; ...
- mysql下一个版本应该且实现并不复杂增加的常用功能
1.innodb的auto_increment应该在参考oracle的实现方式,定期持久化: 我们目前遇到个问题,出于性能考虑,我们每天会把当天处理完成的数据归到另外一张历史表,并清空,同时有可能会重 ...
- golang实现并发爬虫一(单任务版本爬虫功能)
目的是写一个golang并发爬虫版本的演化过程. 那么在演化之前,当然是先跑通一下单任务版本的架构. 正如人走路之前是一定要学会爬走一般. 首先看一下单任务版本的爬虫架构,如下: 这是单任务版本爬虫的 ...
- CentOS以及Oracle数据库发展历史及各版本新功能介绍, 便于构造环境时有个对应关系
CentOS版本历史 版本 CentOS版本号有两个部分,一个主要版本和一个次要版本,主要和次要版本号分别对应于RHEL的主要版本与更新包,CentOS采取从RHEL的源代码包来构建.例如CentOS ...
- spring和mybatis集成,自动生成model、mapper,增加mybatis分页功能
软件简介 Spring是一个流行的控制反转(IoC)和面向切面(AOP)的容器框架,在java webapp开发中使用广泛.http://projects.spring.io/spring-frame ...
- LevelDB源码之五Current文件\Manifest文件\版本信息
版本信息有什么用?先来简要说明三个类的具体用途: Version:代表了某一时刻的数据库版本信息,版本信息的主要内容是当前各个Level的SSTable数据文件列表. VersionSet:维护了一份 ...
- Apache Kafka 0.11版本新功能简介
Apache Kafka近日推出0.11版本.这是一个里程碑式的大版本,特别是Kafka从这个版本开始支持“exactly-once”语义(下称EOS, exactly-once semantics) ...
- 在定制工作项时,把“团队项目”作为变量获取生成版本信息
有用户最近提出这个需求: 通过工作项定制,新增一个字段用以保存项目Bug的"影响版本"信息,但是需要从当前团队项目的服务器生成纪录中获取版本的选项,类似默认模板中的"发现 ...
随机推荐
- 解决Mac安装软件的“已损坏,无法打开...”问题
解决Mac安装软件的"已损坏,无法打开. 您应该将它移到废纸篓"问题 不管在安装时会遇到以已损坏无法打开的困惑, 解决: 一.允许"任何来源"开启 苹果从mac ...
- tracking调研
常用框架有以下三种: Separate Detection and Embedding (SDE- 物体检测,特征提取与物体关联),JOINT Detection and Embeddin ...
- JavaScript – Rest Parameters & Spread Operator
介绍 Rest 和 Spread 的共同点是语法都是 ... (点点点). 但它们的概念是相反的. 看例子体会: Rest Parameters 参考: 阮一峰 – rest 参数 rest para ...
- @vue/cli eslint插件使用指南
使用步骤 使用 npm 安装 @vue/cli-service 版本对应的 @vue/cli-plugin-eslint 例如:"@vue/cli-service": " ...
- 算法学习-CDQ分治
对于二维偏序,为普通的求逆序对,只需要先排序一遍,然后树状数组或双指针即可 而三位偏序甚至更高,则需要用 CDQ 分治,简单来说,就是将树状数组和双指针结合 操作步骤如下: 1.开始将数组按第一维排序 ...
- Python写入数据到MySQL数据库并读取
1.导入pymysql库 命令行输入pip3 install PyMySQL 2.连接数据库 import pymysql db = pymysql.connect(host='localh ...
- QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家
QT数据可视化框架编程实战之三维曲面图 实时变化的三维曲面图 补天云QT技术培训专家 简介 本文将介绍QT数据可视化框架编程实战之三维曲面图,本文通过构造一个数据实时变化的三维曲面图的应用实例来展示Q ...
- 国产OS 中标麒麟下 C# 桌面应用开发环境搭建笔记
1.中标麒麟 7.0 x86 桌面版 默认安装创建用户时,如果没勾选 root 用户使用相同的口令,那么安装完成以后,root 是没有设置口令的,通过 sudo passwd root 输入当前普通用 ...
- emmc寿命
EMMC器件寿命 1)先确认EMMC器件NAND FLASH类型,是MLC还是TLC,一般是TLC,器件手册标称1000-3000次,取平均值2000次作为评估: 2)在OS下查看EMMC器件当前使用 ...
- vant2 List 组件 下拉加载 onLoad
ps:loading finished onLoad 两个变量一个函数 : async onLoad() { console.log("onload"); // 异步更新数据 // ...