2018-07-06 01:42:09 +09:00
|
|
|
package main // import "amuz.es/src/infra/cpu_ctrl"
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"syscall"
|
|
|
|
"fmt"
|
|
|
|
zlog "amuz.es/src/infra/goutils/logger/zap"
|
|
|
|
"go.uber.org/zap/zapcore"
|
|
|
|
"go.uber.org/multierr"
|
|
|
|
"amuz.es/src/infra/goutils/logger/rotater"
|
|
|
|
"amuz.es/src/infra/goutils/handler"
|
|
|
|
"amuz.es/src/infra/cpu_ctrl/daemon"
|
|
|
|
"amuz.es/src/infra/cpu_ctrl/producer"
|
|
|
|
"amuz.es/src/infra/cpu_ctrl/consumer"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
|
|
|
func finalCloser() {
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
fmt.Fprintln(os.Stderr, err.(error).Error())
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 로그 초기화
|
|
|
|
func initLogger() func() {
|
|
|
|
// 로깅설정
|
|
|
|
formatter := zapcore.NewConsoleEncoder(zlog.LogCommonFormat)
|
|
|
|
|
2018-07-06 01:57:59 +09:00
|
|
|
level := zap.InfoLevel
|
2018-07-09 04:54:24 +09:00
|
|
|
if *verbose {
|
|
|
|
level = zap.DebugLevel
|
2018-07-06 01:57:59 +09:00
|
|
|
}
|
2018-07-06 01:42:09 +09:00
|
|
|
// 전역 로거 초기화
|
|
|
|
var err error
|
|
|
|
logger, err = zlog.Init(
|
|
|
|
true,
|
|
|
|
formatter,
|
|
|
|
name,
|
|
|
|
"Stderr",
|
|
|
|
"",
|
|
|
|
nil,
|
2018-07-06 01:57:59 +09:00
|
|
|
level,
|
2018-07-06 01:42:09 +09:00
|
|
|
)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
// 로깅종료 및 exitcode 설정
|
|
|
|
return func() {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 애플리케이션이 종료를 위해 대기하는 부분
|
|
|
|
func initContext(handler *handler.Handler) (func(), func()) {
|
|
|
|
exitSignal := make(chan os.Signal, 1)
|
|
|
|
// return waiter
|
|
|
|
return func() {
|
|
|
|
daemon.NotifyDaemon(daemon.DaemonStarted)
|
|
|
|
// 시그널 처리
|
|
|
|
signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR1)
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-handler.Done():
|
|
|
|
logger.Info("self destruct to close this application")
|
|
|
|
return
|
|
|
|
case initialErr := <-handler.Error():
|
|
|
|
// 복구불가능한 에러(들) 모아서 넘겨주는 부분
|
|
|
|
merged := initialErr
|
|
|
|
logger.Error("main: ", initialErr)
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case anotherErr := <-handler.Error():
|
|
|
|
merged = multierr.Append(merged, anotherErr)
|
|
|
|
logger.Error("main: ", anotherErr)
|
|
|
|
default:
|
|
|
|
// panic을 발생시켜 컨텍스트를 에러를 전달한다.
|
|
|
|
panic(merged)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case sysSignal := <-exitSignal:
|
|
|
|
//handle signal
|
|
|
|
switch sysSignal {
|
|
|
|
case syscall.SIGUSR1:
|
|
|
|
rotater.Rotate()
|
|
|
|
default:
|
|
|
|
logger.Info(sysSignal.String(), " received")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, // return closer
|
|
|
|
func() {
|
|
|
|
daemon.NotifyDaemon(daemon.DaemonStopping)
|
|
|
|
logger.Info("main: main context waiting..")
|
|
|
|
// http 서버 기다린다.
|
|
|
|
handler.GracefulWait()
|
|
|
|
close(exitSignal)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 메인 웹서버 초기화
|
|
|
|
func initProcessor(handler *handler.Handler) func() {
|
|
|
|
|
2018-07-09 04:54:24 +09:00
|
|
|
FanoutOsMetricInfo := func(sender <-chan producer.OSMetricInfo, receivers ...chan<- producer.OSMetricInfo) {
|
|
|
|
defer func() {
|
|
|
|
for _, receiver := range receivers {
|
|
|
|
close(receiver)
|
|
|
|
}
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
handler.NotifyError(err.(error))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
for metric := range sender {
|
|
|
|
for _, receiver := range receivers {
|
|
|
|
select {
|
|
|
|
case receiver <- metric:
|
|
|
|
default:
|
|
|
|
logger.Warn("Some OSMetricInfo consumer blocked!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-10 01:34:52 +09:00
|
|
|
//FanoutSpeed := func(sender <-chan producer.FanspeedInfo, receivers ...chan<- producer.FanspeedInfo) {
|
|
|
|
// defer func() {
|
|
|
|
// for _, receiver := range receivers {
|
|
|
|
// close(receiver)
|
|
|
|
// }
|
|
|
|
// if err := recover(); err != nil {
|
|
|
|
// handler.NotifyError(err.(error))
|
|
|
|
// }
|
|
|
|
// }()
|
|
|
|
// for speed := range sender {
|
|
|
|
// for _, receiver := range receivers {
|
|
|
|
// select {
|
|
|
|
// case receiver <- speed:
|
|
|
|
// default:
|
|
|
|
// logger.Warn("Some Fanspeed consumer blocked!")
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
//FanoutTempeture := func(sender <-chan producer.TempetureInfo, receivers ...chan<- producer.TempetureInfo) {
|
|
|
|
// defer func() {
|
|
|
|
//
|
|
|
|
// for _, receiver := range receivers {
|
|
|
|
// close(receiver)
|
|
|
|
// }
|
|
|
|
// if err := recover(); err != nil {
|
|
|
|
// handler.NotifyError(err.(error))
|
|
|
|
// }
|
|
|
|
// }()
|
|
|
|
// for tempeture := range sender {
|
|
|
|
// for _, receiver := range receivers {
|
|
|
|
// select {
|
|
|
|
// case receiver <- tempeture:
|
|
|
|
// default:
|
|
|
|
// logger.Warn("Some Tempeture consumer blocked!")
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
//processorCount := producer.GetProcessorCount()
|
|
|
|
//if processorCount == 0 {
|
|
|
|
// panic(errors.New("cpu not found!"))
|
|
|
|
//}
|
2018-07-06 01:42:09 +09:00
|
|
|
|
2018-07-09 04:54:24 +09:00
|
|
|
osMetricInfoChan := producer.NewOsMetric(
|
|
|
|
handler,
|
|
|
|
*SampleInterval,
|
|
|
|
)
|
2018-07-10 01:34:52 +09:00
|
|
|
//tempetureInfoChan, fanspeedChan := producer.AggregateProcessorChannel(
|
|
|
|
// handler,
|
|
|
|
// *SampleInterval, processorCount,
|
|
|
|
// *P, *I, *D,
|
|
|
|
// *SetPoint,
|
|
|
|
//)
|
2018-07-09 04:54:24 +09:00
|
|
|
simpleLogger := consumer.NewSampleOSLogger(*SampleInterval, handler)
|
2018-07-10 01:34:52 +09:00
|
|
|
//fanController := consumer.NewFanControl(processorCount, *SampleInterval, handler)
|
|
|
|
//metricLogger := consumer.NewInfluxMetric((*InfluxHost).String(), processorCount, handler)
|
2018-07-06 01:42:09 +09:00
|
|
|
|
2018-07-09 04:54:24 +09:00
|
|
|
handler.IncreaseWait()
|
|
|
|
go simpleLogger.StartControl()
|
2018-07-10 01:34:52 +09:00
|
|
|
//handler.IncreaseWait()
|
|
|
|
//go fanController.StartControl()
|
|
|
|
//handler.IncreaseWait()
|
|
|
|
//go metricLogger.StartLogging()
|
2018-07-06 01:42:09 +09:00
|
|
|
|
2018-07-09 04:54:24 +09:00
|
|
|
go FanoutOsMetricInfo(osMetricInfoChan, simpleLogger.Consumer())
|
2018-07-10 01:34:52 +09:00
|
|
|
//go FanoutOsMetricInfo(osMetricInfoChan, simpleLogger.Consumer(), metricLogger.OsMetricConsumer())
|
|
|
|
//go FanoutTempeture(tempetureInfoChan, metricLogger.TempetureConsumer())
|
|
|
|
//go FanoutSpeed(fanspeedChan, fanController.Consumer(), metricLogger.FanSpeedConsumer())
|
2018-07-06 01:42:09 +09:00
|
|
|
|
|
|
|
return func() {}
|
|
|
|
}
|