Commit 6dab9d9c authored by luxq's avatar luxq

update server

parent 9c68a30f
.idea
build
.PHONY: default manager all clean fmt docker
GOBIN = $(shell pwd)/build/bin
TAG ?= latest
GOFILES_NOVENDOR := $(shell go list -f "{{.Dir}}" ./...)
VERSION := $(shell git describe --tags)
COMMIT_SHA1 := $(shell git rev-parse HEAD)
AppName := manager
default: manager
all: manager
BUILD_FLAGS = -tags netgo -ldflags "\
-X github.com/odysseus/nodemanager/versions.AppName=${AppName} \
-X github.com/odysseus/nodemanager/versions.TagVersion=${VERSION} \
-X 'github.com/odysseus/nodemanager/versions.BuildTime=`date`' \
-X github.com/odysseus/nodemanager/versions.CommitSha1=${COMMIT_SHA1} \
-X 'github.com/odysseus/nodemanager/versions.GoVersion=`go version`' \
-X 'github.com/odysseus/nodemanager/versions.GitBranch=`git symbolic-ref --short -q HEAD`' \
"
manager:
go build $(BUILD_FLAGS) -o=${GOBIN}/$@ -gcflags "all=-N -l" ./cmd/manager
@echo "Done building."
clean:
rm -fr build/*
docker:
docker build -t manager:${TAG} .
package main
import "runtime"
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
Execute()
}
package main
import (
"fmt"
"github.com/odysseus/nodemanager/versions"
"github.com/spf13/cobra"
)
var versionDetail bool
func init() {
RootCmd.AddCommand(versionCmd)
versionDetail = *versionCmd.Flags().BoolP("detail", "d", true, "Print detail version info")
}
// versionCmd represents the base command when called without any subcommands
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print version number",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
if versionDetail {
fmt.Println(versions.DetailVersion())
} else {
fmt.Println(versions.Version())
}
},
}
package main
import (
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/odysseus/nodemanager/config"
"github.com/odysseus/nodemanager/server"
"github.com/rifflock/lfshook"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"time"
"os"
"sync"
)
var logLevel string
var logPath string
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: "manager",
Short: "The node manager command-line interface",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
runNode()
},
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
}
func Execute() {
if err := RootCmd.Execute(); err != nil {
log.Fatal(err)
os.Exit(-1)
}
}
func init() {
cobra.OnInitialize(initConfig)
RootCmd.PersistentFlags().StringVar(&logLevel, "loglevel", "info", "log level")
RootCmd.PersistentFlags().StringVar(&logPath, "logpath", "", "log path")
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
InitLog()
viper.SetConfigName("config") // name of config file (without extension)
viper.AddConfigPath(".")
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
//log.Info("Using config file:", viper.ConfigFileUsed())
} else {
log.WithField("error", err).Fatal("Read config failed")
return
}
_, err := config.ParseConfig(viper.ConfigFileUsed())
if err != nil {
log.WithField("error", err).Fatal("parse config failed")
}
}
func runNode() {
server.StartService()
wg := sync.WaitGroup{}
wg.Add(1)
wg.Wait()
}
func getLogLevel(level string) log.Level {
switch level {
case "info":
return log.InfoLevel
case "debug":
return log.DebugLevel
case "error":
return log.ErrorLevel
default:
return log.InfoLevel
}
}
func InitLog() {
// standard setting
log.SetLevel(getLogLevel(logLevel))
log.SetFormatter(&log.TextFormatter{FullTimestamp: true, TimestampFormat: "2006-01-02 15:04:05.000"})
// file system logger setting
if logPath != "" {
localFilesystemLogger(logPath)
}
}
func logWriter(logPath string) *rotatelogs.RotateLogs {
logFullPath := logPath
logwriter, err := rotatelogs.New(
logFullPath+".%Y%m%d",
rotatelogs.WithLinkName(logFullPath),
rotatelogs.WithRotationSize(100*1024*1024), // 100MB
rotatelogs.WithRotationTime(24*time.Hour),
)
if err != nil {
panic(err)
}
return logwriter
}
func localFilesystemLogger(logPath string) {
lfHook := lfshook.NewHook(logWriter(logPath), &log.TextFormatter{FullTimestamp: true, TimestampFormat: "2006-01-02 15:04:05.000"})
log.AddHook(lfHook)
}
package config
import (
"github.com/BurntSushi/toml"
log "github.com/sirupsen/logrus"
"io/ioutil"
)
type Config struct {
Endpoint string `json:"endpoint" toml:"endpoint"`
MetricsPort int `json:"metrics_port" toml:"metrics_port"`
}
var _cfg *Config = nil
func (conf *Config) MetricPort() int {
return conf.MetricsPort
}
func ParseConfig(path string) (*Config, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
log.Error("get config failed", "err", err)
panic(err)
}
err = toml.Unmarshal(data, &_cfg)
// err = json.Unmarshal(data, &_cfg)
if err != nil {
log.Error("unmarshal config failed", "err", err)
panic(err)
}
return _cfg, nil
}
func GetConfig() *Config {
return _cfg
}
var (
DefaultCors = []string{"localhost"} // Default cors domain for the apis
DefaultVhosts = []string{"localhost"} // Default virtual hosts for the apis
DefaultOrigins = []string{"localhost"} // Default origins for the apis
DefaultPrefix = "" // Default prefix for the apis
DefaultModules = []string{"time"}
)
const (
APIBatchItemLimit = 2000
APIBatchResponseSizeLimit = 250 * 1000 * 1000
)
module github.com/odysseus/nodemanager
go 1.18
require (
github.com/BurntSushi/toml v1.3.2
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/odysseus/odysseus-protocol v0.0.0-00010101000000-000000000000
github.com/prometheus/client_golang v1.18.0
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/spf13/viper v1.18.2
google.golang.org/grpc v1.60.1
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/lestrrat-go/strftime v1.0.6 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/odysseus/odysseus-protocol => ../odysseus-protocol
This diff is collapsed.
package metrics
import (
"fmt"
"github.com/odysseus/nodemanager/config"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"net/http"
_ "net/http/pprof"
)
const (
Namespace = "nodemanager"
)
func NewRegisteredCounterVec(subname string, name string, labels []string) *prometheus.CounterVec {
counterVec := prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: Namespace,
Subsystem: subname,
Name: name,
},
labels,
)
prometheus.MustRegister(counterVec)
return counterVec
}
func NewRegisteredGauge(subname string, name string, labels []string) *prometheus.GaugeVec {
gaugeVec := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: subname,
Name: name,
},
labels,
)
prometheus.MustRegister(gaugeVec)
return gaugeVec
}
func NewRegisteredGaugeNoVec(subname string, name string) prometheus.Gauge {
gaugeVec := prometheus.NewGauge(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: subname,
Name: name,
},
)
prometheus.MustRegister(gaugeVec)
return gaugeVec
}
func NewRegisteredHistogram(subname string, name string, labels []string) *prometheus.HistogramVec {
histogramVec := prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: Namespace,
Subsystem: subname,
Name: name,
},
labels,
)
prometheus.MustRegister(histogramVec)
return histogramVec
}
func NewRegisteredSummary(subname string, name string, labels []string) *prometheus.SummaryVec {
summaryVec := prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Namespace: Namespace,
Subsystem: subname,
Name: name,
},
labels,
)
prometheus.MustRegister(summaryVec)
return summaryVec
}
func NewRegisteredMeter(subname string, name string) prometheus.Counter {
counter := prometheus.NewCounter(
prometheus.CounterOpts{
Namespace: Namespace,
Subsystem: subname,
Name: name,
},
)
prometheus.MustRegister(counter)
return counter
}
func StartMetrics() {
addr := fmt.Sprintf(":%d", config.GetConfig().MetricPort())
http.Handle("/metrics", promhttp.Handler())
err := http.ListenAndServe(addr, nil)
if err != nil {
log.Errorf("metrics server exit: %s", err.Error())
}
}
package apibackend
type Backend interface {
BloomStatus() (uint64, uint64)
}
type nodeBackend struct {
}
func (b *nodeBackend) BloomStatus() (uint64, uint64) {
return 0, 0
}
func NewBackend() Backend {
return &nodeBackend{}
}
package server
import (
"errors"
"fmt"
"github.com/odysseus/nodemanager/config"
"github.com/odysseus/nodemanager/server/apibackend"
"net"
omanager "github.com/odysseus/odysseus-protocol/gen/proto/go/nodemanager/v1"
"google.golang.org/grpc"
)
var (
ErrParams = errors.New("invalid request")
ErrUnSupport = errors.New("unsupport feature")
)
type NodeManagerService struct {
backend apibackend.Backend
quit chan struct{}
omanager.UnimplementedNodeManagerServiceServer
}
func registerService(server *grpc.Server) {
bend := apibackend.NewBackend()
omanager.RegisterNodeManagerServiceServer(server, &NodeManagerService{backend: bend, quit: make(chan struct{})})
}
func StartService() {
lis, err := net.Listen("tcp", config.GetConfig().Endpoint)
if err != nil {
fmt.Printf("failed to listen: %v", err)
return
}
s := grpc.NewServer(grpc.MaxSendMsgSize(1024*1024*20), grpc.MaxRecvMsgSize(1024*1024*20))
registerService(s)
err = s.Serve(lis)
if err != nil {
fmt.Printf("failed to serve: %v", err)
return
}
}
package versions
import (
"fmt"
"github.com/odysseus/nodemanager/metrics"
)
var (
TagVersion string
AppName string
BuildTime string
GoVersion string
GitBranch string
CommitSha1 string
)
func init() {
metrics.NewRegisteredGauge("version", "gauge",
[]string{"version", "buildTime", "gitBranch", "gitCommit", "goVersion", "appName"}).
WithLabelValues(TagVersion, BuildTime, GitBranch, CommitSha1, GoVersion, AppName).Set(1)
}
func Version() string {
return fmt.Sprintf("%s-%s-v%s\n", AppName, BuildTime, TagVersion)
}
func DetailVersion() string {
var info = make([]byte, 0)
info = append(info, fmt.Sprintf("AppName:\t%s\n", AppName)...)
info = append(info, fmt.Sprintf("Version:\t%s\n", TagVersion)...)
info = append(info, fmt.Sprintf("GitBranch:\t%s\n", GitBranch)...)
info = append(info, fmt.Sprintf("GitCommit:\t%s\n", CommitSha1)...)
info = append(info, fmt.Sprintf("BuildTime:\t%s\n", BuildTime)...)
return string(info)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment