forked from ccfos/huatuo
227 lines
5.9 KiB
Go
227 lines
5.9 KiB
Go
// Copyright 2025 The HuaTuo Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"runtime"
|
|
"strings"
|
|
"syscall"
|
|
|
|
_ "huatuo-bamai/core/autotracing"
|
|
_ "huatuo-bamai/core/events"
|
|
_ "huatuo-bamai/core/metrics"
|
|
"huatuo-bamai/internal/bpf"
|
|
"huatuo-bamai/internal/conf"
|
|
"huatuo-bamai/internal/log"
|
|
"huatuo-bamai/internal/pod"
|
|
"huatuo-bamai/internal/services"
|
|
"huatuo-bamai/internal/storage"
|
|
"huatuo-bamai/internal/utils/cgrouputil"
|
|
"huatuo-bamai/internal/utils/pidutil"
|
|
"huatuo-bamai/pkg/tracing"
|
|
|
|
"github.com/urfave/cli/v2"
|
|
)
|
|
|
|
func mainAction(ctx *cli.Context) error {
|
|
if ctx.NArg() > 0 {
|
|
return fmt.Errorf("invalid param %v", ctx.Args())
|
|
}
|
|
|
|
if err := pidutil.LockPidFile(ctx.App.Name); err != nil {
|
|
return fmt.Errorf("failed to lock pid file: %w", err)
|
|
}
|
|
defer pidutil.RemovePidFile(ctx.App.Name)
|
|
|
|
// init cpu quota
|
|
host, err := cgrouputil.NewRuntimeCgroup(ctx.App.Name,
|
|
conf.Get().RuntimeCgroup.LimitInitCPU,
|
|
conf.Get().RuntimeCgroup.LimitMem)
|
|
if err != nil {
|
|
return fmt.Errorf("new cgroup: %w", err)
|
|
}
|
|
defer host.Delete()
|
|
|
|
// initialize the storage clients.
|
|
storageInitCtx := storage.InitContext{
|
|
EsAddresses: conf.Get().Storage.ES.Address,
|
|
EsUsername: conf.Get().Storage.ES.Username,
|
|
EsPassword: conf.Get().Storage.ES.Password,
|
|
EsIndex: conf.Get().Storage.ES.Index,
|
|
LocalPath: conf.Get().Storage.LocalFile.Path,
|
|
LocalMaxRotation: conf.Get().Storage.LocalFile.MaxRotation,
|
|
LocalRotationSize: conf.Get().Storage.LocalFile.RotationSize,
|
|
Region: conf.Region,
|
|
}
|
|
|
|
if err := storage.InitDefaultClients(&storageInitCtx); err != nil {
|
|
return fmt.Errorf("storage.InitDefaultClients: %w", err)
|
|
}
|
|
|
|
// init the bpf manager.
|
|
if err := bpf.InitBpfManager(); err != nil {
|
|
return fmt.Errorf("failed to init bpf manager: %w", err)
|
|
}
|
|
|
|
if err := pod.ContainerCgroupCssInit(); err != nil {
|
|
return fmt.Errorf("init pod cgroup metadata: %w", err)
|
|
}
|
|
|
|
blackListed := conf.Get().Tracing.BlackList
|
|
mgr, err := tracing.NewMgrTracingEvent(blackListed)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := mgr.MgrTracingEventStartAll(); err != nil {
|
|
return err
|
|
}
|
|
|
|
prom, err := InitMetricsCollector(blackListed, conf.Region)
|
|
if err != nil {
|
|
return fmt.Errorf("InitMetricsCollector: %w", err)
|
|
}
|
|
|
|
log.Infof("Initialize the Metrics collector: %v", prom)
|
|
|
|
services.Start(conf.Get().APIServer.TCPAddr, mgr, prom)
|
|
|
|
// update cpu quota
|
|
if err := host.UpdateCPU(conf.Get().RuntimeCgroup.LimitCPU); err != nil {
|
|
return fmt.Errorf("cg update cpu: %w", err)
|
|
}
|
|
|
|
waitExit := make(chan os.Signal, 1)
|
|
signal.Notify(waitExit, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGUSR1, syscall.SIGINT, syscall.SIGTERM)
|
|
for {
|
|
s := <-waitExit
|
|
switch s {
|
|
case syscall.SIGQUIT, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM:
|
|
log.Infof("huatuo-bamai exit by signal %d", s)
|
|
bpf.CloseBpfManager()
|
|
return nil
|
|
case syscall.SIGUSR1:
|
|
return nil
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
var (
|
|
// AppGitCommit will be the hash that the binary was built from
|
|
// and will be populated by the Makefile
|
|
AppGitCommit string
|
|
// AppBuildTime will be populated by the Makefile
|
|
AppBuildTime string
|
|
// AppVersion will be populated by the Makefile, read from
|
|
// VERSION file of the source code.
|
|
AppVersion string
|
|
AppUsage = "An In-depth Observation of Linux Kernel Application"
|
|
)
|
|
|
|
func main() {
|
|
app := cli.NewApp()
|
|
app.Usage = AppUsage
|
|
|
|
if AppVersion == "" {
|
|
panic("the value of AppVersion must be specified")
|
|
}
|
|
|
|
v := []string{
|
|
"",
|
|
fmt.Sprintf(" app_version: %s", AppVersion),
|
|
fmt.Sprintf(" go_version: %s", runtime.Version()),
|
|
fmt.Sprintf(" git_commit: %s", AppGitCommit),
|
|
fmt.Sprintf(" build_time: %s", AppBuildTime),
|
|
}
|
|
app.Version = strings.Join(v, "\n")
|
|
|
|
app.Flags = []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: "config",
|
|
Value: "huatuo-bamai.conf",
|
|
Usage: "huatuo-bamai config file",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "region",
|
|
Required: true,
|
|
Usage: "the host and containers are in this region",
|
|
},
|
|
&cli.StringSliceFlag{
|
|
Name: "disable-tracing",
|
|
Usage: "disable tracing. This is related to TracerConfig.BlackList in config, and complement each other",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "log-debug",
|
|
Usage: "enable debug output for logging",
|
|
},
|
|
}
|
|
|
|
app.Before = func(ctx *cli.Context) error {
|
|
if err := conf.LoadConfig(ctx.String("config")); err != nil {
|
|
return fmt.Errorf("failed to load config: %w", err)
|
|
}
|
|
|
|
// set Region
|
|
conf.Region = ctx.String("region")
|
|
|
|
// log level
|
|
if conf.Get().LogLevel != "" {
|
|
log.SetLevel(conf.Get().LogLevel)
|
|
log.Infof("log level [%s] configured in file, use it", log.GetLevel())
|
|
}
|
|
|
|
logFile := conf.Get().LogFile
|
|
if logFile != "" {
|
|
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)
|
|
if err == nil {
|
|
log.SetOutput(file)
|
|
} else {
|
|
log.SetOutput(os.Stdout)
|
|
log.Infof("Failed to log to file, using default stdout")
|
|
}
|
|
}
|
|
|
|
// tracer
|
|
disabledTracing := ctx.StringSlice("disable-tracing")
|
|
if len(disabledTracing) > 0 {
|
|
definedTracers := conf.Get().Tracing.BlackList
|
|
definedTracers = append(definedTracers, disabledTracing...)
|
|
|
|
conf.Set("TracerConfig.BlackList", definedTracers)
|
|
log.Infof("The tracer black list by cli: %v", conf.Get().Tracing.BlackList)
|
|
}
|
|
|
|
if ctx.Bool("log-debug") {
|
|
log.SetLevel("Debug")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// core
|
|
app.Action = mainAction
|
|
|
|
// run
|
|
if err := app.Run(os.Args); err != nil {
|
|
log.Errorf("Error: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|