You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by ne...@apache.org on 2017/04/19 21:32:13 UTC
[2/4] incubator-trafficcontrol git commit: Add TM2 polling config log
location changes
Add TM2 polling config log location changes
Also simplifies the FilePoller.
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/7697b5b1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/7697b5b1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/7697b5b1
Branch: refs/heads/master
Commit: 7697b5b1380855fdd562c14b0ad9f02bbb6d42b7
Parents: 240043f
Author: Robert Butts <ro...@gmail.com>
Authored: Wed Mar 29 16:55:20 2017 -0600
Committer: David Neuman <da...@gmail.com>
Committed: Wed Apr 19 15:31:43 2017 -0600
----------------------------------------------------------------------
.../common/handler/handler.go | 28 +---
traffic_monitor_golang/common/poller/poller.go | 41 -----
.../traffic_monitor/config/config.go | 59 ++++++-
.../traffic_monitor/manager/manager.go | 38 ++++-
.../traffic_monitor/manager/opsconfig.go | 167 +++++++++----------
.../traffic_monitor/poller/file.go | 60 +++++++
.../traffic_monitor/traffic_monitor.go | 46 +----
7 files changed, 242 insertions(+), 197 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/7697b5b1/traffic_monitor_golang/common/handler/handler.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/common/handler/handler.go b/traffic_monitor_golang/common/handler/handler.go
index 587238a..3b001c6 100644
--- a/traffic_monitor_golang/common/handler/handler.go
+++ b/traffic_monitor_golang/common/handler/handler.go
@@ -20,11 +20,8 @@ package handler
*/
import (
- "encoding/json"
"io"
"time"
-
- "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/log"
)
const (
@@ -33,16 +30,6 @@ const (
NOTIFY_ALWAYS
)
-type Handler interface {
- Handle(string, io.Reader, time.Duration, time.Time, error, uint64, chan<- uint64)
-}
-
-type OpsConfigFileHandler struct {
- Content interface{}
- ResultChannel chan interface{}
- OpsConfigChannel chan OpsConfig
-}
-
type OpsConfig struct {
Username string `json:"username"`
Password string `json:"password"`
@@ -52,17 +39,6 @@ type OpsConfig struct {
HttpListener string `json:"httpListener"`
}
-func (handler OpsConfigFileHandler) Listen() {
- for {
- result := <-handler.ResultChannel
- var toc OpsConfig
-
- err := json.Unmarshal(result.([]byte), &toc)
-
- if err != nil {
- log.Errorf("Could not unmarshal Ops Config JSON: %s\n", err)
- } else {
- handler.OpsConfigChannel <- toc
- }
- }
+type Handler interface {
+ Handle(string, io.Reader, time.Duration, time.Time, error, uint64, chan<- uint64)
}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/7697b5b1/traffic_monitor_golang/common/poller/poller.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/common/poller/poller.go b/traffic_monitor_golang/common/poller/poller.go
index 9b760d6..6d85713 100644
--- a/traffic_monitor_golang/common/poller/poller.go
+++ b/traffic_monitor_golang/common/poller/poller.go
@@ -20,15 +20,12 @@ package poller
*/
import (
- "io/ioutil"
"math/rand"
"net/http"
"os"
"sync/atomic"
"time"
- "gopkg.in/fsnotify.v1"
-
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/fetcher"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/handler"
instr "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/instrumentation"
@@ -93,12 +90,6 @@ func NewHTTP(
}
}
-type FilePoller struct {
- File string
- ResultChannel chan interface{}
- NotificationChannel chan int
-}
-
type MonitorCfg struct {
CDN string
Cfg to.TrafficMonitorConfigMap
@@ -348,38 +339,6 @@ func insomniacPoller(pollerId int64, polls []HTTPPollInfo, fetcherTemplate fetch
}
}
-func (p FilePoller) Poll() {
- // initial read before watching for changes
- contents, err := ioutil.ReadFile(p.File)
-
- if err != nil {
- log.Errorf("reading %s: %s\n", p.File, err)
- os.Exit(1) // TODO: this is a little drastic -jse
- } else {
- p.ResultChannel <- contents
- }
-
- watcher, _ := fsnotify.NewWatcher()
- watcher.Add(p.File)
-
- for {
- select {
- case event := <-watcher.Events:
- if event.Op&fsnotify.Write == fsnotify.Write {
- contents, err := ioutil.ReadFile(p.File)
-
- if err != nil {
- log.Errorf("opening %s: %s\n", p.File, err)
- } else {
- p.ResultChannel <- contents
- }
- }
- case err := <-watcher.Errors:
- log.Errorln(time.Now(), "error:", err)
- }
- }
-}
-
// diffConfigs takes the old and new configs, and returns a list of deleted IDs, and a list of new polls to do
func diffConfigs(old HttpPollerConfig, new HttpPollerConfig) ([]string, []HTTPPollInfo) {
deletions := []string{}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/7697b5b1/traffic_monitor_golang/traffic_monitor/config/config.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/config/config.go b/traffic_monitor_golang/traffic_monitor/config/config.go
index 1941ec6..7e1752b 100644
--- a/traffic_monitor_golang/traffic_monitor/config/config.go
+++ b/traffic_monitor_golang/traffic_monitor/config/config.go
@@ -21,8 +21,13 @@ package config
import (
"encoding/json"
+ "fmt"
+ "io"
"io/ioutil"
+ "os"
"time"
+
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/log"
)
// LogLocation is a location to log to. This may be stdout, stderr, null (/dev/null), or a valid file path.
@@ -179,8 +184,58 @@ func Load(fileName string) (Config, error) {
return cfg, nil
}
configBytes, err := ioutil.ReadFile(fileName)
- if err == nil {
- err = json.Unmarshal(configBytes, &cfg)
+ if err != nil {
+ return DefaultConfig, err
}
+ return LoadBytes(configBytes)
+}
+
+// LoadBytes loads the given file bytes.
+func LoadBytes(bytes []byte) (Config, error) {
+ cfg := DefaultConfig
+ err := json.Unmarshal(bytes, &cfg)
return cfg, err
}
+
+func getLogWriter(location string) (io.WriteCloser, error) {
+ switch location {
+ case LogLocationStdout:
+ return log.NopCloser(os.Stdout), nil
+ case LogLocationStderr:
+ return log.NopCloser(os.Stderr), nil
+ case LogLocationNull:
+ return log.NopCloser(ioutil.Discard), nil
+ default:
+ return os.OpenFile(location, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
+ }
+}
+
+func GetLogWriters(cfg Config) (io.WriteCloser, io.WriteCloser, io.WriteCloser, io.WriteCloser, io.WriteCloser, error) {
+ eventLoc := cfg.LogLocationEvent
+ errLoc := cfg.LogLocationError
+ warnLoc := cfg.LogLocationWarning
+ infoLoc := cfg.LogLocationInfo
+ debugLoc := cfg.LogLocationDebug
+
+ eventW, err := getLogWriter(eventLoc)
+ if err != nil {
+ return nil, nil, nil, nil, nil, fmt.Errorf("getting log event writer %v: %v", eventLoc, err)
+ }
+ errW, err := getLogWriter(errLoc)
+ if err != nil {
+ return nil, nil, nil, nil, nil, fmt.Errorf("getting log error writer %v: %v", errLoc, err)
+ }
+ warnW, err := getLogWriter(warnLoc)
+ if err != nil {
+ return nil, nil, nil, nil, nil, fmt.Errorf("getting log warning writer %v: %v", warnLoc, err)
+ }
+ infoW, err := getLogWriter(infoLoc)
+ if err != nil {
+ return nil, nil, nil, nil, nil, fmt.Errorf("getting log info writer %v: %v", infoLoc, err)
+ }
+ debugW, err := getLogWriter(debugLoc)
+ if err != nil {
+ return nil, nil, nil, nil, nil, fmt.Errorf("getting log debug writer %v: %v", debugLoc, err)
+ }
+ return eventW, errW, warnW, infoW, debugW, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/7697b5b1/traffic_monitor_golang/traffic_monitor/manager/manager.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/manager/manager.go b/traffic_monitor_golang/traffic_monitor/manager/manager.go
index 126ca39..4a5391f 100644
--- a/traffic_monitor_golang/traffic_monitor/manager/manager.go
+++ b/traffic_monitor_golang/traffic_monitor/manager/manager.go
@@ -21,25 +21,29 @@ package manager
import (
"crypto/tls"
+ "fmt"
"net/http"
+ "github.com/davecheney/gmx"
+
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/fetcher"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/handler"
+ "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/log"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/poller"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/cache"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/config"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/health"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/peer"
+ simplepoller "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/poller"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/threadsafe"
todata "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/trafficopsdata"
towrap "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/trafficopswrapper"
- "github.com/davecheney/gmx"
)
//
// Start starts the poller and handler goroutines
//
-func Start(opsConfigFile string, cfg config.Config, staticAppData config.StaticAppData) {
+func Start(opsConfigFile string, cfg config.Config, staticAppData config.StaticAppData, trafficMonitorConfigFileName string) error {
toSession := towrap.ITrafficOpsSession(towrap.NewTrafficOpsSessionThreadsafe(nil))
counters := fetcher.Counters{
Success: gmx.NewCounter("fetchSuccess"),
@@ -155,7 +159,12 @@ func Start(opsConfigFile string, cfg config.Config, staticAppData config.StaticA
cfg,
)
+ if err := startMonitorConfigFilePoller(trafficMonitorConfigFileName); err != nil {
+ return fmt.Errorf("starting monitor config file poller: %v", err)
+ }
+
healthTickListener(cacheHealthPoller.TickChan, healthIteration)
+ return nil
}
// healthTickListener listens for health ticks, and writes to the health iteration variable. Does not return.
@@ -164,3 +173,28 @@ func healthTickListener(cacheHealthTick <-chan uint64, healthIteration threadsaf
healthIteration.Set(i)
}
}
+
+func startMonitorConfigFilePoller(filename string) error {
+ onChange := func(bytes []byte, err error) {
+ if err != nil {
+ log.Errorf("monitor config file poll, polling file '%v': %v", filename, err)
+ return
+ }
+
+ cfg, err := config.LoadBytes(bytes)
+ if err != nil {
+ log.Errorf("monitor config file poll, loading bytes '%v' from '%v': %v", string(bytes), filename, err)
+ return
+ }
+
+ eventW, errW, warnW, infoW, debugW, err := config.GetLogWriters(cfg)
+ if err != nil {
+ log.Errorf("monitor config file poll, getting log writers '%v': %v", filename, err)
+ return
+ }
+ log.Init(eventW, errW, warnW, infoW, debugW)
+ }
+
+ _, err := simplepoller.File(filename, onChange)
+ return err
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/7697b5b1/traffic_monitor_golang/traffic_monitor/manager/opsconfig.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/manager/opsconfig.go b/traffic_monitor_golang/traffic_monitor/manager/opsconfig.go
index e2a275d..a184d42 100644
--- a/traffic_monitor_golang/traffic_monitor/manager/opsconfig.go
+++ b/traffic_monitor_golang/traffic_monitor/manager/opsconfig.go
@@ -20,16 +20,17 @@ package manager
*/
import (
+ "encoding/json"
"fmt"
"time"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/handler"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/log"
- "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/common/poller"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/config"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/datareq"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/health"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/peer"
+ poller "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/poller"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/srvhttp"
"github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/threadsafe"
todata "github.com/apache/incubator-trafficcontrol/traffic_monitor_golang/traffic_monitor/trafficopsdata"
@@ -65,110 +66,104 @@ func StartOpsConfigManager(
unpolledCaches threadsafe.UnpolledCaches,
monitorConfig threadsafe.TrafficMonitorConfigMap,
cfg config.Config,
-) threadsafe.OpsConfig {
+) (threadsafe.OpsConfig, error) {
- opsConfigFileChannel := make(chan interface{})
- opsConfigFilePoller := poller.FilePoller{
- File: opsConfigFile,
- ResultChannel: opsConfigFileChannel,
+ handleErr := func(err error) {
+ errorCount.Inc()
+ log.Errorf("OpsConfigManager: %v\n", err)
}
- opsConfigChannel := make(chan handler.OpsConfig)
- opsConfigFileHandler := handler.OpsConfigFileHandler{
- ResultChannel: opsConfigFilePoller.ResultChannel,
- OpsConfigChannel: opsConfigChannel,
- }
-
- go opsConfigFileHandler.Listen()
- go opsConfigFilePoller.Poll()
-
+ httpServer := srvhttp.Server{}
opsConfig := threadsafe.NewOpsConfig()
// TODO remove change subscribers, give Threadsafes directly to the things that need them. If they only set vars, and don't actually do work on change.
- go func() {
- handleErr := func(err error) {
- errorCount.Inc()
- log.Errorf("OpsConfigManager: %v\n", err)
+ onChange := func(bytes []byte, err error) {
+ if err != nil {
+ handleErr(err)
+ return
}
- httpServer := srvhttp.Server{}
+ newOpsConfig := handler.OpsConfig{}
+ if err = json.Unmarshal(bytes, &newOpsConfig); err != nil {
+ handleErr(fmt.Errorf("Could not unmarshal Ops Config JSON: %s\n", err))
+ return
+ }
- for newOpsConfig := range opsConfigChannel {
- // TODO config? parameter?
- useCache := false
- trafficOpsRequestTimeout := time.Second * time.Duration(10)
- realToSession, err := to.LoginWithAgent(newOpsConfig.Url, newOpsConfig.Username, newOpsConfig.Password, newOpsConfig.Insecure, staticAppData.UserAgent, useCache, trafficOpsRequestTimeout)
- if err != nil {
- handleErr(fmt.Errorf("instantiating Session with traffic_ops: %s\n", err))
- continue
- }
+ opsConfig.Set(newOpsConfig)
- if cdn, err := getMonitorCDN(realToSession, staticAppData.Hostname); err != nil {
- handleErr(fmt.Errorf("getting CDN name from Traffic Ops, using config CDN '%s': %s\n", newOpsConfig.CdnName, err))
- } else {
- if newOpsConfig.CdnName != "" && newOpsConfig.CdnName != cdn {
- log.Warnf("%s Traffic Ops CDN '%s' doesn't match config CDN '%s' - using Traffic Ops CDN\n", staticAppData.Hostname, cdn, newOpsConfig.CdnName)
- }
- newOpsConfig.CdnName = cdn
- }
+ listenAddress := ":80" // default
- opsConfig.Set(newOpsConfig)
+ if newOpsConfig.HttpListener != "" {
+ listenAddress = newOpsConfig.HttpListener
+ }
- listenAddress := ":80" // default
+ endpoints := datareq.MakeDispatchMap(
+ opsConfig,
+ toSession,
+ localStates,
+ peerStates,
+ combinedStates,
+ statInfoHistory,
+ statResultHistory,
+ statMaxKbpses,
+ healthHistory,
+ dsStats,
+ events,
+ staticAppData,
+ healthPollInterval,
+ lastHealthDurations,
+ fetchCount,
+ healthIteration,
+ errorCount,
+ toData,
+ localCacheStatus,
+ lastStats,
+ unpolledCaches,
+ monitorConfig,
+ )
+ err = httpServer.Run(endpoints, listenAddress, cfg.ServeReadTimeout, cfg.ServeWriteTimeout, cfg.StaticFileDir)
+ if err != nil {
+ handleErr(fmt.Errorf("MonitorConfigPoller: error creating HTTP server: %s\n", err))
+ return
+ }
- if newOpsConfig.HttpListener != "" {
- listenAddress = newOpsConfig.HttpListener
- }
+ // TODO config? parameter?
+ useCache := false
+ trafficOpsRequestTimeout := time.Second * time.Duration(10)
- endpoints := datareq.MakeDispatchMap(
- opsConfig,
- toSession,
- localStates,
- peerStates,
- combinedStates,
- statInfoHistory,
- statResultHistory,
- statMaxKbpses,
- healthHistory,
- dsStats,
- events,
- staticAppData,
- healthPollInterval,
- lastHealthDurations,
- fetchCount,
- healthIteration,
- errorCount,
- toData,
- localCacheStatus,
- lastStats,
- unpolledCaches,
- monitorConfig,
- )
-
- if err := httpServer.Run(endpoints, listenAddress, cfg.ServeReadTimeout, cfg.ServeWriteTimeout, cfg.StaticFileDir); err != nil {
- handleErr(fmt.Errorf("creating HTTP server: %s\n", err))
- continue
- }
-
- toSession.Set(realToSession)
+ realToSession, err := to.LoginWithAgent(newOpsConfig.Url, newOpsConfig.Username, newOpsConfig.Password, newOpsConfig.Insecure, staticAppData.UserAgent, useCache, trafficOpsRequestTimeout)
+ if err != nil {
+ handleErr(fmt.Errorf("MonitorConfigPoller: error instantiating Session with traffic_ops: %s\n", err))
+ return
+ }
+ toSession.Set(realToSession)
- if err := toData.Fetch(toSession, newOpsConfig.CdnName); err != nil {
- handleErr(fmt.Errorf("getting Traffic Ops data: %v\n", err))
- continue
+ if cdn, err := getMonitorCDN(realToSession, staticAppData.Hostname); err != nil {
+ handleErr(fmt.Errorf("getting CDN name from Traffic Ops, using config CDN '%s': %s\n", newOpsConfig.CdnName, err))
+ } else {
+ if newOpsConfig.CdnName != "" && newOpsConfig.CdnName != cdn {
+ log.Warnf("%s Traffic Ops CDN '%s' doesn't match config CDN '%s' - using Traffic Ops CDN\n", staticAppData.Hostname, cdn, newOpsConfig.CdnName)
}
+ newOpsConfig.CdnName = cdn
+ }
- // These must be in a goroutine, because the monitorConfigPoller tick sends to a channel this select listens for. Thus, if we block on sends to the monitorConfigPoller, we have a livelock race condition.
- // More generically, we're using goroutines as an infinite chan buffer, to avoid potential livelocks
- for _, subscriber := range opsConfigChangeSubscribers {
- go func(s chan<- handler.OpsConfig) { s <- newOpsConfig }(subscriber)
- }
- for _, subscriber := range toChangeSubscribers {
- go func(s chan<- towrap.ITrafficOpsSession) { s <- toSession }(subscriber)
- }
+ if err := toData.Fetch(toSession, newOpsConfig.CdnName); err != nil {
+ handleErr(fmt.Errorf("Error getting Traffic Ops data: %v\n", err))
+ return
}
- }()
- return opsConfig
+ // These must be in a goroutine, because the monitorConfigPoller tick sends to a channel this select listens for. Thus, if we block on sends to the monitorConfigPoller, we have a livelock race condition.
+ // More generically, we're using goroutines as an infinite chan buffer, to avoid potential livelocks
+ for _, subscriber := range opsConfigChangeSubscribers {
+ go func(s chan<- handler.OpsConfig) { s <- newOpsConfig }(subscriber)
+ }
+ for _, subscriber := range toChangeSubscribers {
+ go func(s chan<- towrap.ITrafficOpsSession) { s <- toSession }(subscriber)
+ }
+ }
+
+ _, err := poller.File(opsConfigFile, onChange)
+ return opsConfig, err
}
// getMonitorCDN returns the CDN of a given Traffic Monitor.
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/7697b5b1/traffic_monitor_golang/traffic_monitor/poller/file.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/poller/file.go b/traffic_monitor_golang/traffic_monitor/poller/file.go
new file mode 100644
index 0000000..fdd89d8
--- /dev/null
+++ b/traffic_monitor_golang/traffic_monitor/poller/file.go
@@ -0,0 +1,60 @@
+package poller
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import (
+ "fmt"
+ "gopkg.in/fsnotify.v1"
+ "io/ioutil"
+)
+
+// FilePoller starts a goroutine polling the given file for changes. When changes occur, including an initial read, the result callback is called asynchronously. Returns a kill chan, which will kill the file poller when written to.
+func File(filename string, result func([]byte, error)) (chan<- struct{}, error) {
+ die := make(chan struct{})
+
+ contents, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return nil, fmt.Errorf("reading file '%v': %v", filename, err)
+ }
+ go result(contents, nil)
+
+ watcher, err := fsnotify.NewWatcher()
+ if err != nil {
+ return nil, err
+ }
+ go func() {
+ watcher.Add(filename)
+ defer watcher.Close()
+ for {
+ select {
+ case event := <-watcher.Events:
+ if event.Op&fsnotify.Write == fsnotify.Write {
+ go result(ioutil.ReadFile(filename))
+ }
+ case err := <-watcher.Errors:
+ go result(nil, err)
+ case <-die:
+ return
+ }
+ }
+ }()
+
+ return die, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/7697b5b1/traffic_monitor_golang/traffic_monitor/traffic_monitor.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/traffic_monitor.go b/traffic_monitor_golang/traffic_monitor/traffic_monitor.go
index fe7dc38..1395ceb 100644
--- a/traffic_monitor_golang/traffic_monitor/traffic_monitor.go
+++ b/traffic_monitor_golang/traffic_monitor/traffic_monitor.go
@@ -22,8 +22,6 @@ package main
import (
"flag"
"fmt"
- "io"
- "io/ioutil"
"os"
"runtime"
@@ -40,42 +38,6 @@ var GitRevision = "No Git Revision Specified. Please build with '-X main.GitRevi
// BuildTimestamp is the time the app was built. The app SHOULD always be built with this set via the `-X` flag.
var BuildTimestamp = "No Build Timestamp Specified. Please build with '-X main.BuildTimestamp=`date +'%Y-%M-%dT%H:%M:%S'`"
-func getLogWriter(location string) (io.WriteCloser, error) {
- switch location {
- case config.LogLocationStdout:
- return log.NopCloser(os.Stdout), nil
- case config.LogLocationStderr:
- return log.NopCloser(os.Stderr), nil
- case config.LogLocationNull:
- return log.NopCloser(ioutil.Discard), nil
- default:
- return os.OpenFile(location, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
- }
-}
-func getLogWriters(eventLoc, errLoc, warnLoc, infoLoc, debugLoc string) (io.WriteCloser, io.WriteCloser, io.WriteCloser, io.WriteCloser, io.WriteCloser, error) {
- eventW, err := getLogWriter(eventLoc)
- if err != nil {
- return nil, nil, nil, nil, nil, fmt.Errorf("getting log event writer %v: %v", eventLoc, err)
- }
- errW, err := getLogWriter(errLoc)
- if err != nil {
- return nil, nil, nil, nil, nil, fmt.Errorf("getting log error writer %v: %v", errLoc, err)
- }
- warnW, err := getLogWriter(warnLoc)
- if err != nil {
- return nil, nil, nil, nil, nil, fmt.Errorf("getting log warning writer %v: %v", warnLoc, err)
- }
- infoW, err := getLogWriter(infoLoc)
- if err != nil {
- return nil, nil, nil, nil, nil, fmt.Errorf("getting log info writer %v: %v", infoLoc, err)
- }
- debugW, err := getLogWriter(debugLoc)
- if err != nil {
- return nil, nil, nil, nil, nil, fmt.Errorf("getting log debug writer %v: %v", debugLoc, err)
- }
- return eventW, errW, warnW, infoW, debugW, nil
-}
-
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
@@ -101,7 +63,7 @@ func main() {
os.Exit(1)
}
- eventW, errW, warnW, infoW, debugW, err := getLogWriters(cfg.LogLocationEvent, cfg.LogLocationError, cfg.LogLocationWarning, cfg.LogLocationInfo, cfg.LogLocationDebug)
+ eventW, errW, warnW, infoW, debugW, err := config.GetLogWriters(cfg)
if err != nil {
fmt.Printf("Error starting service: failed to create log writers: %v\n", err)
os.Exit(1)
@@ -110,5 +72,9 @@ func main() {
log.Infof("Starting with config %+v\n", cfg)
- manager.Start(*opsConfigFile, cfg, staticData)
+ err = manager.Start(*opsConfigFile, cfg, staticData, *configFileName)
+ if err != nil {
+ fmt.Printf("Error starting service: failed to start managers: %v\n", err)
+ os.Exit(1)
+ }
}