forked from cwtch.im/cwtch
remove config sample; now generate config and populate defaults; add config to control logging
This commit is contained in:
parent
8a1fb3ccc2
commit
addd5a7b00
|
@ -2,28 +2,14 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
cwtchserver "cwtch.im/cwtch/server"
|
cwtchserver "cwtch.im/cwtch/server"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
serverConfigFile = "serverConfig.json"
|
serverConfigFile = "serverConfig.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
func confirmOrCopySampleConfig() {
|
|
||||||
// if no config file, attempt to copy sample
|
|
||||||
if _, err := os.Stat(serverConfigFile); os.IsNotExist(err) {
|
|
||||||
raw, err := ioutil.ReadFile(serverConfigFile + ".sample")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Could not read sample config to copy: ", err)
|
|
||||||
}
|
|
||||||
ioutil.WriteFile(serverConfigFile, raw, 0600)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
confirmOrCopySampleConfig()
|
|
||||||
serverConfig := cwtchserver.LoadConfig(serverConfigFile)
|
serverConfig := cwtchserver.LoadConfig(serverConfigFile)
|
||||||
|
|
||||||
server := new(cwtchserver.Server)
|
server := new(cwtchserver.Server)
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"maxBufferLines": 100000,
|
|
||||||
"serverReporting": {
|
|
||||||
"reportingGroupId": "",
|
|
||||||
"reportingServerAddr": ""
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,10 +23,12 @@ type Monitors struct {
|
||||||
ClientConns MonitorHistory
|
ClientConns MonitorHistory
|
||||||
starttime time.Time
|
starttime time.Time
|
||||||
breakChannel chan bool
|
breakChannel chan bool
|
||||||
|
log bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start initializes a Monitors's monitors
|
// Start initializes a Monitors's monitors
|
||||||
func (mp *Monitors) Start(ra *application.RicochetApplication) {
|
func (mp *Monitors) Start(ra *application.RicochetApplication, log bool) {
|
||||||
|
mp.log = log
|
||||||
mp.starttime = time.Now()
|
mp.starttime = time.Now()
|
||||||
mp.breakChannel = make(chan bool)
|
mp.breakChannel = make(chan bool)
|
||||||
mp.MessageCounter = NewCounter()
|
mp.MessageCounter = NewCounter()
|
||||||
|
@ -35,19 +37,15 @@ func (mp *Monitors) Start(ra *application.RicochetApplication) {
|
||||||
mp.Memory = NewMonitorHistory(MegaBytes, func() float64 { sysInfo, _ := pidusage.GetStat(os.Getpid()); return float64(sysInfo.Memory) })
|
mp.Memory = NewMonitorHistory(MegaBytes, func() float64 { sysInfo, _ := pidusage.GetStat(os.Getpid()); return float64(sysInfo.Memory) })
|
||||||
mp.ClientConns = NewMonitorHistory(Count, func() float64 { return float64(ra.ConnectionCount()) })
|
mp.ClientConns = NewMonitorHistory(Count, func() float64 { return float64(ra.ConnectionCount()) })
|
||||||
|
|
||||||
// Todo: replace with proper reporting
|
if mp.log {
|
||||||
go mp.log()
|
go mp.run()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *Monitors) log() {
|
func (mp *Monitors) run() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-time.After(time.Minute):
|
case <-time.After(time.Minute):
|
||||||
messageMinutes := mp.Messages.Minutes()
|
|
||||||
cpuMinutes := mp.CPU.Minutes()
|
|
||||||
memoryMinutes := mp.Memory.Minutes()
|
|
||||||
listenConnsMinutes := mp.ClientConns.Minutes()
|
|
||||||
log.Printf("METRICS: Messages: %.0f ClientConns: %.0f CPU: %.2f Memory: %.0fMBs\n", messageMinutes[0], listenConnsMinutes[0], cpuMinutes[0], memoryMinutes[0]/1024/1024)
|
|
||||||
mp.report()
|
mp.report()
|
||||||
case <-mp.breakChannel:
|
case <-mp.breakChannel:
|
||||||
return
|
return
|
||||||
|
@ -80,12 +78,13 @@ func (mp *Monitors) report() {
|
||||||
mp.Memory.Report(w)
|
mp.Memory.Report(w)
|
||||||
|
|
||||||
w.Flush()
|
w.Flush()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops all the monitors in a Monitors
|
// Stop stops all the monitors in a Monitors
|
||||||
func (mp *Monitors) Stop() {
|
func (mp *Monitors) Stop() {
|
||||||
|
if mp.log {
|
||||||
mp.breakChannel <- true
|
mp.breakChannel <- true
|
||||||
|
}
|
||||||
mp.Messages.Stop()
|
mp.Messages.Stop()
|
||||||
mp.CPU.Stop()
|
mp.CPU.Stop()
|
||||||
mp.Memory.Stop()
|
mp.Memory.Stop()
|
||||||
|
|
|
@ -23,7 +23,7 @@ type Server struct {
|
||||||
func (s *Server) Run(serverConfig *Config) {
|
func (s *Server) Run(serverConfig *Config) {
|
||||||
s.config = serverConfig
|
s.config = serverConfig
|
||||||
cwtchserver := new(application.RicochetApplication)
|
cwtchserver := new(application.RicochetApplication)
|
||||||
s.metricsPack.Start(cwtchserver)
|
s.metricsPack.Start(cwtchserver, s.config.ServerReporting.LogMetricsToFile)
|
||||||
|
|
||||||
l, err := application.SetupOnion("127.0.0.1:9051", "tcp4", "", s.config.PrivateKey(), 9878)
|
l, err := application.SetupOnion("127.0.0.1:9051", "tcp4", "", s.config.PrivateKey(), 9878)
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
// Reporting is a struct for storing a the config a server needs to be a peer, and connect to a group to report
|
// Reporting is a struct for storing a the config a server needs to be a peer, and connect to a group to report
|
||||||
type Reporting struct {
|
type Reporting struct {
|
||||||
|
LogMetricsToFile bool `json:"logMetricsToFile"`
|
||||||
PeerPrivateKey string `json:"privateKey"`
|
PeerPrivateKey string `json:"privateKey"`
|
||||||
ReportingGroupID string `json:"reportingGroupId"`
|
ReportingGroupID string `json:"reportingGroupId"`
|
||||||
ReportingServerAddr string `json:"reportingServerAddr"`
|
ReportingServerAddr string `json:"reportingServerAddr"`
|
||||||
|
@ -41,30 +42,43 @@ func (config *Config) Save(filename string) {
|
||||||
ioutil.WriteFile(filename, bytes, 0600)
|
ioutil.WriteFile(filename, bytes, 0600)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newConfig generates a simple config with defaults. Unmarshal will return them if they aren't specified
|
||||||
|
func newConfig() *Config {
|
||||||
|
config := Config{}
|
||||||
|
config.MaxBufferLines = 100000
|
||||||
|
config.ServerReporting.LogMetricsToFile = false
|
||||||
|
|
||||||
|
return &config
|
||||||
|
}
|
||||||
|
|
||||||
// LoadConfig loads a Config from a json file specified by filename
|
// LoadConfig loads a Config from a json file specified by filename
|
||||||
func LoadConfig(filename string) *Config {
|
func LoadConfig(filename string) *Config {
|
||||||
raw, err := ioutil.ReadFile(filename)
|
config := newConfig()
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Could not read config: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
config := Config{}
|
raw, err := ioutil.ReadFile(filename)
|
||||||
|
if err == nil {
|
||||||
err = json.Unmarshal(raw, &config)
|
err = json.Unmarshal(raw, &config)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error reading config: ", err)
|
log.Println("Error reading config: ", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configAutoPopulate(config)
|
||||||
|
// Always save (first time generation, new version with new variables populated)
|
||||||
|
config.Save(filename)
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto populate required values if missing and save
|
||||||
|
func configAutoPopulate(config *Config) {
|
||||||
if config.PrivateKeyBytes == "" {
|
if config.PrivateKeyBytes == "" {
|
||||||
config.generatePrivateKey()
|
config.generatePrivateKey()
|
||||||
config.Save(filename)
|
|
||||||
}
|
|
||||||
if config.ServerReporting.PeerPrivateKey == "" {
|
|
||||||
config.generatePeerPrivateKey()
|
|
||||||
config.Save(filename)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &config
|
if config.ServerReporting.PeerPrivateKey == "" {
|
||||||
|
config.generatePeerPrivateKey()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) generatePrivateKey() {
|
func (config *Config) generatePrivateKey() {
|
||||||
|
|
Loading…
Reference in New Issue