cmd/ptp4u/main.go (99 lines of code) (raw):

/* Copyright (c) Facebook, Inc. and its affiliates. 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 ( "flag" "fmt" "net" "net/http" _ "net/http/pprof" "time" "github.com/facebook/time/ptp/ptp4u/drain" "github.com/facebook/time/ptp/ptp4u/server" "github.com/facebook/time/ptp/ptp4u/stats" "github.com/facebook/time/timestamp" log "github.com/sirupsen/logrus" ) func main() { c := &server.Config{} var ipaddr string var pprofaddr string flag.IntVar(&c.DSCP, "dscp", 0, "DSCP for PTP packets, valid values are between 0-63 (used by send workers)") flag.StringVar(&ipaddr, "ip", "::", "IP to bind on") flag.StringVar(&pprofaddr, "pprofaddr", "", "host:port for the pprof to bind") flag.StringVar(&c.Interface, "iface", "eth0", "Set the interface") flag.StringVar(&c.LogLevel, "loglevel", "warning", "Set a log level. Can be: debug, info, warning, error") flag.DurationVar(&c.MinSubInterval, "minsubinterval", 1*time.Second, "Minimum interval of the sync/announce subscription messages") flag.DurationVar(&c.MaxSubDuration, "maxsubduration", 1*time.Hour, "Maximum sync/announce/delay_resp subscription duration") flag.StringVar(&c.TimestampType, "timestamptype", timestamp.HWTIMESTAMP, fmt.Sprintf("Timestamp type. Can be: %s, %s", timestamp.HWTIMESTAMP, timestamp.SWTIMESTAMP)) flag.DurationVar(&c.UTCOffset, "utcoffset", 37*time.Second, "Set the UTC offset. Ignored if shm or leapsectz are set") flag.BoolVar(&c.Leapsectz, "leapsectz", false, "Leapsectz to determine UTC offset periodically") flag.BoolVar(&c.SHM, "shm", false, "Use Share Memory Segment to determine UTC offset periodically (leapsectz has a priority)") flag.IntVar(&c.SendWorkers, "workers", 100, "Set the number of send workers") flag.IntVar(&c.RecvWorkers, "recvworkers", 10, "Set the number of receive workers") flag.IntVar(&c.MonitoringPort, "monitoringport", 8888, "Port to run monitoring server on") flag.IntVar(&c.QueueSize, "queue", 0, "Size of the queue to send out packets") flag.DurationVar(&c.MetricInterval, "metricinterval", 1*time.Minute, "Interval of resetting metrics") flag.DurationVar(&c.DrainInterval, "draininterval", 30*time.Second, "Interval for drain checks") flag.UintVar(&c.ClockClass, "classclass", 6, "Clock class to report via announce messages. 6 - Locked with Primary Reference Clock") flag.UintVar(&c.ClockAccuracy, "clockaccuracy", 0x21, "Clock accuracy to report via announce messages. // 0x21 - Time Accurate within 100ns") flag.Parse() switch c.LogLevel { case "debug": log.SetLevel(log.DebugLevel) case "info": log.SetLevel(log.InfoLevel) case "warning": log.SetLevel(log.WarnLevel) case "error": log.SetLevel(log.ErrorLevel) default: log.Fatalf("Unrecognized log level: %v", c.LogLevel) } if c.DSCP < 0 || c.DSCP > 63 { log.Fatalf("Unsupported DSCP value %v", c.DSCP) } switch c.TimestampType { case timestamp.SWTIMESTAMP: log.Warning("Software timestamps greatly reduce the precision") fallthrough case timestamp.HWTIMESTAMP: log.Debugf("Using %s timestamps", c.TimestampType) default: log.Fatalf("Unrecognized timestamp type: %s", c.TimestampType) } c.IP = net.ParseIP(ipaddr) found, err := c.IfaceHasIP() if err != nil { log.Fatal(err) } if !found { log.Fatalf("IP '%s' is not found on interface '%s'", c.IP, c.Interface) } if pprofaddr != "" { log.Warningf("Staring profiler on %s", pprofaddr) go func() { log.Println(http.ListenAndServe(pprofaddr, nil)) }() } if c.Leapsectz { if err := c.SetUTCOffsetFromLeapsectz(); err != nil { log.Fatalf("Failed to set UTC offset: %v", err) } } else if c.SHM { if err := c.SetUTCOffsetFromSHM(); err != nil { log.Fatalf("Failed to set UTC offset: %v", err) } } log.Infof("UTC offset is: %v", c.UTCOffset) // Monitoring // Replace with your implementation of Stats st := stats.NewJSONStats() go st.Start(c.MonitoringPort) // drain check check := &drain.FileDrain{FileName: "/var/tmp/kill_ptp4u"} checks := []drain.Drain{check} s := server.Server{ Config: c, Stats: st, Checks: checks, } if err := s.Start(); err != nil { log.Fatalf("Server run failed: %v", err) } }