【Temporal】日志打印控制
开启server日志级别
首先我们从代码出发看看应该怎么开启,进入到temporal server的启动入口:temporal/cmd/server/main.go
logger := log.NewZapLogger(log.BuildZapLogger(cfg.Log))
logger.Info("Build info.",
tag.NewTimeTag("git-time", build.InfoData.GitTime),
tag.NewStringTag("git-revision", build.InfoData.GitRevision),
tag.NewBoolTag("git-modified", build.InfoData.GitModified),
tag.NewStringTag("go-arch", build.InfoData.GoArch),
tag.NewStringTag("go-os", build.InfoData.GoOs),
tag.NewStringTag("go-version", build.InfoData.GoVersion),
tag.NewBoolTag("cgo-enabled", build.InfoData.CgoEnabled),
tag.NewStringTag("server-version", headers.ServerVersion),
tag.NewBoolTag("debug-mode", debug.Enabled),
)
var dynamicConfigClient dynamicconfig.Client
if cfg.DynamicConfigClient != nil {
dynamicConfigClient, err = dynamicconfig.NewFileBasedClient(cfg.DynamicConfigClient, logger, temporal.InterruptCh())
if err != nil {
return cli.Exit(fmt.Sprintf("Unable to create dynamic config client. Error: %v", err), 1)
}
} else {
dynamicConfigClient = dynamicconfig.NewNoopClient()
logger.Info("Dynamic config client is not configured. Using noop client.")
}
authorizer, err := authorization.GetAuthorizerFromConfig(
&cfg.Global.Authorization,
)
if err != nil {
return cli.Exit(fmt.Sprintf("Unable to instantiate authorizer. Error: %v", err), 1)
}
if authorization.IsNoopAuthorizer(authorizer) && !allowNoAuth {
logger.Warn(
"Not using any authorizer and flag `--allow-no-auth` not detected. " +
"Future versions will require using the flag `--allow-no-auth` " +
"if you do not want to set an authorizer.",
)
}
claimMapper, err := authorization.GetClaimMapperFromConfig(&cfg.Global.Authorization, logger)
if err != nil {
return cli.Exit(fmt.Sprintf("Unable to instantiate claim mapper: %v.", err), 1)
}
s, err := temporal.NewServer(
temporal.ForServices(services),
temporal.WithConfig(cfg),
temporal.WithDynamicConfigClient(dynamicConfigClient),
temporal.WithLogger(logger),
temporal.InterruptOn(temporal.InterruptCh()),
temporal.WithAuthorizer(authorizer),
temporal.WithClaimMapper(func(cfg *config.Config) authorization.ClaimMapper {
return claimMapper
}),
)
if err != nil {
return cli.Exit(fmt.Sprintf("Unable to create server. Error: %v.", err), 1)
}
err = s.Start()
if err != nil {
return cli.Exit(fmt.Sprintf("Unable to start server. Error: %v", err), 1)
}
return cli.Exit("All services are stopped.", 0)
上面是一部分的启动代码,可以看到,在构造server的时候传入了一个自定义的logger配置;我们看看这个logger配置,通过代码调用我们可以知道:
func parseZapLevel(level string) zapcore.Level {
switch strings.ToLower(level) {
case "debug":
return zap.DebugLevel
case "info":
return zap.InfoLevel
case "warn":
return zap.WarnLevel
case "error":
return zap.ErrorLevel
case "dpanic":
return zap.DPanicLevel
case "panic":
return zap.PanicLevel
case "fatal":
return zap.FatalLevel
default:
return zap.InfoLevel
}
}
这个日志级别可以通过配置文件的log.level字段来控制。
如果我们是通过temporal提供的k8s集群场景下安装命令来默认安装的话,会自动生成各个组件的configMap,我们找到这个configMap,可以看到是这样的:
log:
stdout: true
level: "debug"
persistence:
defaultStore: default
visibilityStore: visibility
numHistoryShards: 512
datastores:
default:
sql:
pluginName: "mysql"
driverName: "mysql"
databaseName: "temporal"
connectAddr: "11.141.232.141:3306"
connectProtocol: "tcp"
user: root
password: "{{ .Env.TEMPORAL_STORE_PASSWORD }}"
maxConnLifetime: 1h
maxConns: 20
secretName: ""
visibility:
sql:
pluginName: "mysql"
driverName: "mysql"
databaseName: "temporal_visibility"
connectAddr: "11.141.232.141:3306"
connectProtocol: "tcp"
user: "root"
password: "{{ .Env.TEMPORAL_VISIBILITY_STORE_PASSWORD }}"
maxConnLifetime: 1h
maxConns: 20
secretName: ""
global:
membership:
name: temporal
maxJoinDuration: 30s
broadcastAddress: {{ default .Env.POD_IP "0.0.0.0" }}
pprof:
port: 7936
metrics:
tags:
type: history
prometheus:
timerType: histogram
listenAddress: "0.0.0.0:9090"
services:
frontend:
rpc:
grpcPort: 7233
membershipPort: 6933
bindOnIP: "0.0.0.0"
history:
rpc:
grpcPort: 7234
membershipPort: 6934
bindOnIP: "0.0.0.0"
matching:
rpc:
grpcPort: 7235
membershipPort: 6935
bindOnIP: "0.0.0.0"
worker:
rpc:
grpcPort: 7239
membershipPort: 6939
bindOnIP: "0.0.0.0"
clusterMetadata:
enableGlobalDomain: false
failoverVersionIncrement: 10
masterClusterName: "active"
currentClusterName: "active"
clusterInformation:
active:
enabled: true
initialFailoverVersion: 1
rpcName: "temporal-frontend"
rpcAddress: "127.0.0.1:7933"
dcRedirectionPolicy:
policy: "noop"
toDC: ""
archival:
status: "disabled"
publicClient:
hostPort: "temporal-frontend:7233"
dynamicConfigClient:
filepath: "/etc/temporal/dynamic_config/dynamic_config.yaml"
pollInterval: "10s"
可以看到配置文件这里可以设置level。
开启SDK日志
在我们代码引入temporal的-go sdk,启动worker的时候,sdk代码里面有部分日志默认是不打印的,比如:
traceLog(func() {
var firstEventID int64 = -1
if response.History != nil && len(response.History.Events) > 0 {
firstEventID = response.History.Events[0].GetEventId()
}
wtp.logger.Debug("workflowTaskPoller::Poll Succeed",
"StartedEventID", response.GetStartedEventId(),
"Attempt", response.GetAttempt(),
"FirstEventID", firstEventID,
"IsQueryTask", response.Query != nil)
})
我们进入这个traceLog方法:
func traceLog(fn func()) {
if enableVerboseLogging {
fn()
}
}
var enableVerboseLogging = false
// EnableVerboseLogging enable or disable verbose logging. This is for internal use only.
func EnableVerboseLogging(enable bool) {
enableVerboseLogging = enable
}
我们可以看到,这些日志时通过一个全局变量来控制的,默认时false,不打印。
并且我们可以看到,sdk提供了一个接口来调用设置这个变量。因此我们可以通过在启动worker的时候,设置这个变量为true。
Choose here javascripttypescripthtmlcssshellpythongolangjavacc++c#phprubyswiftkotlinscalarustdartelixirhaskellluaperlrsql
w := worker.New(*c, taskQueue, worker.Options{
MaxConcurrentWorkflowTaskPollers: 100,
MaxConcurrentActivityTaskPollers: 100,
MaxConcurrentActivityExecutionSize: 1000,
DeadlockDetectionTimeout: time.Second * 60,
EnableLoggingInReplay: true,
})
worker.EnableVerboseLogging(true)