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的"影响版本"信息,但是需要从当前团队项目的服务器生成纪录中获取版本的选项,类似默认模板中的"发现 ...
随机推荐
- 【YashanDB知识库】数据库使用shutdown immediate无响应导致coredump
[标题]数据库使用shutdown immediate无响应导致coredump [问题分类]数据库维护 [关键词]YashanDB, shutdown immediate, coredump [问题 ...
- Goby 漏洞发布|泛微 e-cology v10 appThirdLogin 权限绕过漏洞【漏洞复现】
漏洞名称:泛微 e-cology v10 appThirdLogin 权限绕过漏洞 English Name:Weaver e-cology v10 appThirdLogin Permission ...
- 坑人的opencv安装
我想捡起来C++,最近在看opencv,于是我想着一起吧. 但是我低估了这个小麻烦的魅力,曾经安装opencv c++版本就头秃,如今依然头秃.说明我没长进啊-- 折腾了两天,终于装上了. 其中最麻烦 ...
- canvas图片旋转扩展出原生JS实现移动端横竖屏手写签名示例
前提知识 canvas是提供了各种各样的接口去控制画布,比如旋转rotate方法. 这里的旋转并不是真的把这个画布旋转了,例如ctx.rotate(90 * Math.PI / 180)顺时针旋转90 ...
- ASP.NET Core C# 反射 & 表达式树 (第一篇)
前言 以前就写过几篇关于反射和表达式树的学习笔记, 但是写的很乱. 最近常用到反射和表达式树, 所以特别写一篇做一个整理吧. 泛型和反射 表达式树 学习笔记 c# 常用反射和表达式树整理 反射在项目中 ...
- Azure 入门系列 (第三篇 Publish Web Application to VM)
本系列 这个系列会介绍从 0 到 1 搭建一个 Web Application 的 Server. 间中还会带上一些真实开发常用的功能. 一共 6 篇 1. Virtual Machine (VM) ...
- 记一次 .NET某上位机视觉程序 卡死分析
一:背景 1. 讲故事 前段时间有位朋友找到我,说他的窗体程序在客户这边出现了卡死,让我帮忙看下怎么回事?dump也生成了,既然有dump了那就上 windbg 分析吧. 二:WinDbg 分析 1. ...
- USB gadget驱动框架(六)
本节主要介绍udc驱动枚举过程,需结合udc驱动.composite.c.function等一同分析整个过程. udc驱动中断处理函数 当host检测到DP上拉,则认为有新的device插入,此时ho ...
- 一些git使用命令,误删本地分支,如何找回
1.新建仓库 git init 2.如果要本地更改文件,需要更新到远端. git status # 查看当前文件状态 git add -A # "git add -A" 命令用于将 ...
- python安装sklearn
安装sklearn这个包,首先要安装三个依赖包,如图划红线的部分. 要找这三个包,我们都可以登录:https://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy 这 ...