func (c *JujuLogCommand) Run(ctx *cmd.Context) error { if c.formatFlag != "" { fmt.Fprintf(ctx.Stderr, "--format flag deprecated for command %q", c.Info().Name) } logger := loggo.GetLogger(fmt.Sprintf("unit.%s.juju-log", c.ctx.UnitName())) logLevel := loggo.INFO if c.Debug { logLevel = loggo.DEBUG } else if c.Level != "" { var ok bool logLevel, ok = loggo.ParseLevel(c.Level) if !ok { logger.Warningf("Specified log level of %q is not valid", c.Level) logLevel = loggo.INFO } } prefix := "" if r, err := c.ctx.HookRelation(); err == nil { prefix = r.FakeId() + ": " } else if !errors.IsNotFound(err) { return errors.Trace(err) } logger.Logf(logLevel, "%s%s", prefix, c.Message) return nil }
func (s *LevelSuite) TestParseLevel(c *gc.C) { for _, test := range parseLevelTests { level, ok := loggo.ParseLevel(test.str) c.Assert(level, gc.Equals, test.level) c.Assert(ok, gc.Equals, !test.fail) } }
func parseLogLine(line string) *logLine { const ( agentField = 0 levelField = 3 moduleField = 4 ) fields := strings.Fields(line) result := &logLine{ line: line, } if len(fields) > agentField { agent := fields[agentField] if strings.HasSuffix(agent, ":") { result.agent = agent[:len(agent)-1] } } if len(fields) > moduleField { if level, valid := loggo.ParseLevel(fields[levelField]); valid { result.level = level result.module = fields[moduleField] } } return result }
func (t *LoggingSuite) setUp(c *gc.C) { if _, ok := loggo.ParseLevel(*logConfig); ok { *logConfig = "<root>=" + *logConfig } err := loggo.ConfigureLoggers(*logConfig) c.Assert(err, gc.IsNil) }
func (c *debugLogCommand) Init(args []string) error { if c.level != "" { level, ok := loggo.ParseLevel(c.level) if !ok || level < loggo.TRACE || level > loggo.ERROR { return errors.Errorf("level value %q is not one of %q, %q, %q, %q, %q", c.level, loggo.TRACE, loggo.DEBUG, loggo.INFO, loggo.WARNING, loggo.ERROR) } c.params.Level = level } if c.tail && c.notail { return errors.NotValidf("setting --tail and --no-tail") } if c.utc { c.tz = time.UTC } if c.date { c.format = "2006-01-02 15:04:05" } else { c.format = "15:04:05" } if c.ms { c.format = c.format + ".000" } return cmd.CheckEmpty(args) }
func recordFromAPI(apiRec params.LogStreamRecord, controllerUUID string) (logfwd.Record, error) { rec := logfwd.Record{ ID: apiRec.ID, Timestamp: apiRec.Timestamp, Message: apiRec.Message, } origin, err := originFromAPI(apiRec, controllerUUID) if err != nil { return rec, errors.Trace(err) } rec.Origin = origin loc, err := logfwd.ParseLocation(apiRec.Module, apiRec.Location) if err != nil { return rec, errors.Trace(err) } rec.Location = loc level, ok := loggo.ParseLevel(apiRec.Level) if !ok { return rec, errors.Errorf("unrecognized log level %q", apiRec.Level) } rec.Level = level if err := rec.Validate(); err != nil { return rec, errors.Trace(err) } return rec, nil }
// ServeHTTP implements the http.Handler interface. func (h *logSinkHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { server := websocket.Server{ Handler: func(socket *websocket.Conn) { defer socket.Close() st, entity, err := h.ctxt.stateForRequestAuthenticatedAgent(req) if err != nil { h.sendError(socket, req, err) return } tag := entity.Tag() // Note that this endpoint is agent-only. Thus the only // callers will necessarily provide their Juju version. // // This would be a problem if non-Juju clients (e.g. the // GUI) could use this endpoint since we require that the // *Juju* version be provided as part of the request. Any // attempt to open this endpoint to broader access must // address this caveat appropriately. ver, err := jujuClientVersionFromReq(req) if err != nil { h.sendError(socket, req, err) return } filePrefix := st.ModelUUID() + " " + tag.String() + ":" dbLogger := state.NewDbLogger(st, tag, ver) defer dbLogger.Close() // If we get to here, no more errors to report, so we report a nil // error. This way the first line of the socket is always a json // formatted simple error. h.sendError(socket, req, nil) logCh := h.receiveLogs(socket) for { select { case <-h.ctxt.stop(): return case m := <-logCh: fileErr := h.logToFile(filePrefix, m) if fileErr != nil { logger.Errorf("logging to logsink.log failed: %v", fileErr) } level, _ := loggo.ParseLevel(m.Level) dbErr := dbLogger.Log(m.Time, m.Module, m.Location, level, m.Message) if dbErr != nil { logger.Errorf("logging to DB failed: %v", err) } if fileErr != nil || dbErr != nil { return } } } }, } server.ServeHTTP(w, req) }
func (c *debugLogCommand) Init(args []string) error { if c.level != "" { level, ok := loggo.ParseLevel(c.level) if !ok || level < loggo.TRACE || level > loggo.ERROR { return fmt.Errorf("level value %q is not one of %q, %q, %q, %q, %q", c.level, loggo.TRACE, loggo.DEBUG, loggo.INFO, loggo.WARNING, loggo.ERROR) } c.params.Level = level } return cmd.CheckEmpty(args) }
// Configure the og level of the root logger for the module's process. func (m *ModuleSupport) SetLogLevel(level string) error { // FIXME: maybe move this implementation into the logger package parsed, ok := loggo.ParseLevel(level) if ok && parsed != loggo.UNSPECIFIED { loggo.GetLogger("").SetLogLevel(parsed) safeLog(m, nil).Logf(parsed, "Log level has been reset to %s", level) return nil } else { return fmt.Errorf("%s is not a valid logging level") } }
func readDebugLogParams(queryMap url.Values) (*debugLogParams, error) { params := new(debugLogParams) if value := queryMap.Get("maxLines"); value != "" { num, err := strconv.ParseUint(value, 10, 64) if err != nil { return nil, errors.Errorf("maxLines value %q is not a valid unsigned number", value) } params.maxLines = uint(num) } if value := queryMap.Get("replay"); value != "" { replay, err := strconv.ParseBool(value) if err != nil { return nil, errors.Errorf("replay value %q is not a valid boolean", value) } params.fromTheStart = replay } if value := queryMap.Get("noTail"); value != "" { noTail, err := strconv.ParseBool(value) if err != nil { return nil, errors.Errorf("noTail value %q is not a valid boolean", value) } params.noTail = noTail } if value := queryMap.Get("backlog"); value != "" { num, err := strconv.ParseUint(value, 10, 64) if err != nil { return nil, errors.Errorf("backlog value %q is not a valid unsigned number", value) } params.backlog = uint(num) } if value := queryMap.Get("level"); value != "" { var ok bool level, ok := loggo.ParseLevel(value) if !ok || level < loggo.TRACE || level > loggo.ERROR { return nil, errors.Errorf("level value %q is not one of %q, %q, %q, %q, %q", value, loggo.TRACE, loggo.DEBUG, loggo.INFO, loggo.WARNING, loggo.ERROR) } params.filterLevel = level } params.includeEntity = queryMap["includeEntity"] params.excludeEntity = queryMap["excludeEntity"] params.includeModule = queryMap["includeModule"] params.excludeModule = queryMap["excludeModule"] return params, nil }
func newLogStream(queryMap url.Values) (*logStream, error) { maxLines := uint(0) if value := queryMap.Get("maxLines"); value != "" { num, err := strconv.ParseUint(value, 10, 64) if err != nil { return nil, fmt.Errorf("maxLines value %q is not a valid unsigned number", value) } maxLines = uint(num) } fromTheStart := false if value := queryMap.Get("replay"); value != "" { replay, err := strconv.ParseBool(value) if err != nil { return nil, fmt.Errorf("replay value %q is not a valid boolean", value) } fromTheStart = replay } backlog := uint(0) if value := queryMap.Get("backlog"); value != "" { num, err := strconv.ParseUint(value, 10, 64) if err != nil { return nil, fmt.Errorf("backlog value %q is not a valid unsigned number", value) } backlog = uint(num) } level := loggo.UNSPECIFIED if value := queryMap.Get("level"); value != "" { var ok bool level, ok = loggo.ParseLevel(value) if !ok || level < loggo.TRACE || level > loggo.ERROR { return nil, fmt.Errorf("level value %q is not one of %q, %q, %q, %q, %q", value, loggo.TRACE, loggo.DEBUG, loggo.INFO, loggo.WARNING, loggo.ERROR) } } return &logStream{ includeEntity: queryMap["includeEntity"], includeModule: queryMap["includeModule"], excludeEntity: queryMap["excludeEntity"], excludeModule: queryMap["excludeModule"], maxLines: maxLines, fromTheStart: fromTheStart, backlog: backlog, filterLevel: level, }, nil }
func parseLogLine(line string) *logFileLine { const ( agentTagIndex = 0 levelIndex = 3 moduleIndex = 4 ) fields := strings.Fields(line) result := &logFileLine{ line: line, } if len(fields) > agentTagIndex { agentTag := fields[agentTagIndex] // Drop mandatory trailing colon (:). // Since colon is mandatory, agentTag without it is invalid and will be empty (""). if strings.HasSuffix(agentTag, ":") { result.agentTag = agentTag[:len(agentTag)-1] } /* Drop unit suffix. In logs, unit information may be prefixed with either a unit_tag by itself or a unit_tag[nnnn]. The code below caters for both scenarios. */ if bracketIndex := strings.Index(agentTag, "["); bracketIndex != -1 { result.agentTag = agentTag[:bracketIndex] } // If, at this stage, result.agentTag is empty, we could not deduce the tag. No point getting the name... if result.agentTag != "" { // Entity Name deduced from entity tag entityTag, err := names.ParseTag(result.agentTag) if err != nil { /* Logging error but effectively swallowing it as there is no where to propogate. We don't expect ParseTag to fail since the tag was generated by juju in the first place. */ logger.Errorf("Could not deduce name from tag %q: %v\n", result.agentTag, err) } result.agentName = entityTag.Id() } } if len(fields) > moduleIndex { if level, valid := loggo.ParseLevel(fields[levelIndex]); valid { result.level = level result.module = fields[moduleIndex] } } return result }
func main() { var flagPrivateKey, flagPublicKey, flagIP, flagBind, flagProxy, flagLog, flagDump, flagReplay string var keyPrivate *rsa.PrivateKey var keyPublic *rsa.PublicKey flag.Usage = usage flag.StringVar(&flagPrivateKey, "priv", "", "server private key") flag.StringVar(&flagPublicKey, "pub", "", "client public key") flag.StringVar(&flagLog, "log", "info", "log level (trace, debug, info, warning, error, critical)") flag.StringVar(&flagProxy, "proxy", "", "proxy server to connect to instead of PSO2") flag.StringVar(&flagBind, "bind", "", "interface address to bind on") flag.StringVar(&flagIP, "addr", findaddr(), "external IPv4 address") flag.StringVar(&flagDump, "dump", "", "dump packets to folder") flag.StringVar(&flagReplay, "replay", "", "replay packets from a dump") flag.Parse() ip := net.IPv4(127, 0, 0, 1) if flagIP != "" { ip = net.ParseIP(flagIP) } if flagLog != "" { lvl, ok := loggo.ParseLevel(flagLog) if ok { Logger.SetLogLevel(lvl) } else { Logger.Warningf("Invalid log level %s specified", flagLog) } } pso2net.Logger.SetLogLevel(Logger.LogLevel()) if flagPrivateKey != "" { Logger.Infof("Loading private key") f, err := os.Open(flagPrivateKey) ragequit(flagPrivateKey, err) keyPrivate, err = pso2net.LoadPrivateKey(f) f.Close() ragequit(flagPrivateKey, err) } if flagPublicKey != "" { Logger.Infof("Loading public key") f, err := os.Open(flagPublicKey) ragequit(flagPublicKey, err) keyPublic, err = pso2net.LoadPublicKey(f) f.Close() ragequit(flagPublicKey, err) } if flagReplay != "" { Logger.Infof("Replaying packets from %s", flagReplay) f, err := os.Open(flagReplay) ragequit(flagReplay, err) c := pso2net.NewConnection(util.ReadWriter(f, ioutil.Discard)) var r pso2net.PacketRoute err = c.RoutePackets(&r) ragequit(flagReplay, err) } else { Logger.Infof("Starting proxy servers on %s", ip) fallbackRoute := func(p *pso2net.Proxy) *pso2net.PacketRoute { r := &pso2net.PacketRoute{} r.RouteMask(0xffff, pso2net.RoutePriorityLow, pso2net.ProxyHandlerFallback(p)) if flagDump != "" { r.RouteMask(0xffff, pso2net.RoutePriorityHigh, pso2net.HandlerIgnore(pso2net.HandlerDump(flagDump))) } return r } newProxy := func(host string, port uint16) *pso2net.Proxy { return pso2net.NewProxy(fmt.Sprintf("%s:%d", flagBind, port), fmt.Sprintf("%s:%d", host, port)) } startProxy := func(p *pso2net.Proxy, s *pso2net.PacketRoute, c *pso2net.PacketRoute) { l, err := p.Listen() ragequit(p.String(), err) go p.Start(l, s, c) } hostname := func(ship int) string { if flagProxy != "" { return flagProxy } return packets.ShipHostnames[ship] } endpoints := make(EndpointMap) for i := 0; i < packets.ShipCount; i++ { blockPort := uint16(12000 + (100 * i)) shipPort := uint16(blockPort + 99) // Set up ship proxy, rewrites IPs proxy := newProxy(hostname(i), shipPort) route := &pso2net.PacketRoute{} route.Route(packets.TypeShip, pso2net.RoutePriorityNormal, pso2net.ProxyHandlerShip(proxy, endpoints, ip)) route.RouteMask(0xffff, pso2net.RoutePriorityLow, pso2net.ProxyHandlerFallback(proxy)) if flagDump != "" { route.RouteMask(0xffff, pso2net.RoutePriorityHigh, pso2net.HandlerIgnore(pso2net.HandlerDump(flagDump))) } endpoints[shipPort] = proxy startProxy(proxy, fallbackRoute(proxy), route) // Set up block proxy, rewrites IPs proxy = newProxy(hostname(i), blockPort) route = &pso2net.PacketRoute{} route.Route(packets.TypeBlock, pso2net.RoutePriorityNormal, pso2net.ProxyHandlerBlock(proxy, endpoints, ip)) route.RouteMask(0xffff, pso2net.RoutePriorityLow, pso2net.ProxyHandlerFallback(proxy)) if flagDump != "" { route.RouteMask(0xffff, pso2net.RoutePriorityHigh, pso2net.HandlerIgnore(pso2net.HandlerDump(flagDump))) } endpoints[blockPort] = proxy startProxy(proxy, fallbackRoute(proxy), route) for b := uint16(1); b < 99; b++ { port := blockPort + b proxy = newProxy(hostname(i), port) // Set up client route (messages from the PSO2 server) route = &pso2net.PacketRoute{} route.Route(packets.TypeRoom, pso2net.RoutePriorityNormal, pso2net.ProxyHandlerRoom(proxy, endpoints, ip)) route.Route(packets.TypeRoomTeam, pso2net.RoutePriorityNormal, pso2net.ProxyHandlerRoom(proxy, endpoints, ip)) route.Route(packets.TypeBlockResponse, pso2net.RoutePriorityNormal, pso2net.ProxyHandlerBlockResponse(proxy, endpoints, ip)) route.Route(packets.TypeBlocks, pso2net.RoutePriorityNormal, pso2net.ProxyHandlerBlocks(proxy, endpoints, ip)) route.Route(packets.TypeBlocks2, pso2net.RoutePriorityNormal, pso2net.ProxyHandlerBlocks(proxy, endpoints, ip)) route.RouteMask(0xffff, pso2net.RoutePriorityLow, pso2net.ProxyHandlerFallback(proxy)) if flagDump != "" { route.RouteMask(0xffff, pso2net.RoutePriorityHigh, pso2net.HandlerIgnore(pso2net.HandlerDump(flagDump))) } // Set up server route (messages from the client) sroute := &pso2net.PacketRoute{} sroute.Route(packets.TypeCipher, pso2net.RoutePriorityHigh, pso2net.HandlerIgnore(pso2net.HandlerCipher(keyPrivate))) sroute.Route(packets.TypeCipher, pso2net.RoutePriorityNormal, pso2net.ProxyHandlerCipher(proxy, keyPrivate, keyPublic)) sroute.RouteMask(0xffff, pso2net.RoutePriorityLow, pso2net.ProxyHandlerFallback(proxy)) if flagDump != "" { sroute.RouteMask(0xffff, pso2net.RoutePriorityHigh, pso2net.HandlerIgnore(pso2net.HandlerDump(flagDump))) } endpoints[port] = proxy startProxy(proxy, sroute, route) } } } // Stop foreverz <-make(chan int) }