func (*GlobalSuite) TestRootLogger(c *gc.C) { var root loggo.Logger got := loggo.GetLogger("") c.Check(got.Name(), gc.Equals, root.Name()) c.Check(got.LogLevel(), gc.Equals, root.LogLevel()) }
func releaseContainerAddresses( api APICalls, instanceID instance.Id, namespace instance.Namespace, log loggo.Logger, ) { containerTag, err := namespace.MachineTag(string(instanceID)) if err != nil { // Not a reason to cause StopInstances to fail though.. log.Warningf("unexpected container tag %q: %v", instanceID, err) return } err = api.ReleaseContainerAddresses(containerTag) switch { case err == nil: log.Infof("released all addresses for container %q", containerTag.Id()) case errors.IsNotSupported(err): log.Warningf("not releasing all addresses for container %q: %v", containerTag.Id(), err) default: log.Warningf( "unexpected error trying to release container %q addreses: %v", containerTag.Id(), err, ) } }
func maybeReleaseContainerAddresses( api APICalls, instanceID instance.Id, namespace string, log loggo.Logger, ) { if environs.AddressAllocationEnabled() { // The addresser worker will take care of the addresses. return } // If we're not using addressable containers, we might still have used MAAS // 1.8+ device to register the container when provisioning. In that case we // need to attempt releasing the device, but ignore a NotSupported error // (when we're not using MAAS 1.8+). namespacePrefix := fmt.Sprintf("%s-", namespace) tagString := strings.TrimPrefix(string(instanceID), namespacePrefix) containerTag, err := names.ParseMachineTag(tagString) if err != nil { // Not a reason to cause StopInstances to fail though.. log.Warningf("unexpected container tag %q: %v", instanceID, err) return } err = api.ReleaseContainerAddresses(containerTag) switch { case err == nil: log.Infof("released all addresses for container %q", containerTag.Id()) case errors.IsNotSupported(err): log.Warningf("not releasing all addresses for container %q: %v", containerTag.Id(), err) default: log.Warningf( "unexpected error trying to release container %q addreses: %v", containerTag.Id(), err, ) } }
// AgentDone processes the error returned by // an exiting agent. func AgentDone(logger loggo.Logger, err error) error { err = errors.Cause(err) switch err { case worker.ErrTerminateAgent, worker.ErrRebootMachine, worker.ErrShutdownMachine: err = nil } if ug, ok := err.(*upgrader.UpgradeReadyError); ok { if err := ug.ChangeAgentTools(); err != nil { // Return and let the init system deal with the restart. err = errors.Annotate(err, "cannot change agent tools") logger.Infof(err.Error()) return err } } return err }
func (c *Client) sendRateLimitedRequest(method, URL string, headers http.Header, reqData []byte, logger *loggo.Logger) (resp *http.Response, err error) { for i := 0; i < c.maxSendAttempts; i++ { var reqReader io.Reader if reqData != nil { reqReader = bytes.NewReader(reqData) } req, err := http.NewRequest(method, URL, reqReader) if err != nil { err = errors.Newf(err, "failed creating the request %s", URL) return nil, err } // Setting req.Close to true to avoid malformed HTTP version "nullHTTP/1.1" error // See http://stackoverflow.com/questions/17714494/golang-http-request-results-in-eof-errors-when-making-multiple-requests-successi req.Close = true for header, values := range headers { for _, value := range values { req.Header.Add(header, value) } } req.ContentLength = int64(len(reqData)) resp, err = c.Do(req) if err != nil { return nil, errors.Newf(err, "failed executing the request %s", URL) } if resp.StatusCode != http.StatusRequestEntityTooLarge || resp.Header.Get("Retry-After") == "" { return resp, nil } resp.Body.Close() retryAfter, err := strconv.ParseFloat(resp.Header.Get("Retry-After"), 64) if err != nil { return nil, errors.Newf(err, "Invalid Retry-After header %s", URL) } if retryAfter == 0 { return nil, errors.Newf(err, "Resource limit exeeded at URL %s", URL) } if logger != nil { logger.Warningf("Too many requests, retrying in %dms.", int(retryAfter*1000)) } time.Sleep(time.Duration(retryAfter) * time.Second) } return nil, errors.Newf(err, "Maximum number of attempts (%d) reached sending request to %s", c.maxSendAttempts, URL) }
// AgentDone processes the error returned by an exiting agent. func AgentDone(logger loggo.Logger, err error) error { err = errors.Cause(err) switch err { case worker.ErrTerminateAgent, worker.ErrRebootMachine, worker.ErrShutdownMachine: // These errors are swallowed here because we want to exit // the agent process without error, to avoid the init system // restarting us. err = nil } if ug, ok := err.(*upgrader.UpgradeReadyError); ok { if err := ug.ChangeAgentTools(); err != nil { // Return and let the init system deal with the restart. err = errors.Annotate(err, "cannot change agent tools") logger.Infof(err.Error()) return err } } return err }
func prepareOrGetContainerInterfaceInfo( api APICalls, machineID string, bridgeDevice string, allocateOrMaintain bool, startingNetworkInfo []network.InterfaceInfo, log loggo.Logger, ) ([]network.InterfaceInfo, error) { maintain := !allocateOrMaintain if maintain { log.Debugf("not running maintenance for machine %q", machineID) return nil, nil } log.Debugf("using multi-bridge networking for container %q", machineID) containerTag := names.NewMachineTag(machineID) preparedInfo, err := api.PrepareContainerInterfaceInfo(containerTag) if err != nil { return nil, errors.Trace(err) } log.Tracef("PrepareContainerInterfaceInfo returned %+v", preparedInfo) return preparedInfo, nil }
// RespondDecorator returns an autorest.RespondDecorator that // logs responses at trace level. func RespondDecorator(logger loggo.Logger) autorest.RespondDecorator { return func(r autorest.Responder) autorest.Responder { return autorest.ResponderFunc(func(resp *http.Response) error { if logger.IsTraceEnabled() { dump, err := httputil.DumpResponse(resp, true) if err != nil { logger.Tracef("failed to dump response: %v", err) logger.Tracef("%+v", resp) } else { logger.Tracef("%s", dump) } } return r.Respond(resp) }) } }
// PrepareDecorator returns an autorest.PrepareDecorator that // logs requests at trace level. func PrepareDecorator(logger loggo.Logger) autorest.PrepareDecorator { return func(p autorest.Preparer) autorest.Preparer { return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { if logger.IsTraceEnabled() { dump, err := httputil.DumpRequest(r, true) if err != nil { logger.Tracef("failed to dump request: %v", err) logger.Tracef("%+v", r) } else { logger.Tracef("%s", dump) } } return p.Prepare(r) }) } }
func (s *LoggerSuite) TestRootLogger(c *gc.C) { root := loggo.Logger{} c.Check(root.Name(), gc.Equals, "<root>") c.Check(root.LogLevel(), gc.Equals, loggo.WARNING) c.Check(root.IsErrorEnabled(), gc.Equals, true) c.Check(root.IsWarningEnabled(), gc.Equals, true) c.Check(root.IsInfoEnabled(), gc.Equals, false) c.Check(root.IsDebugEnabled(), gc.Equals, false) c.Check(root.IsTraceEnabled(), gc.Equals, false) }
// Sends the specified request to URL and checks that the HTTP response status is as expected. // reqReader: a reader returning the data to send. // length: the number of bytes to send. // headers: HTTP headers to include with the request. // expectedStatus: a slice of allowed response status codes. func (c *Client) sendRequest(method, URL string, reqReader io.Reader, length int, headers http.Header, expectedStatus []int, logger *loggo.Logger) (rc io.ReadCloser, respHeader *http.Header, err error) { reqData := make([]byte, length) if reqReader != nil { nrRead, err := io.ReadFull(reqReader, reqData) if err != nil { err = errors.Newf(err, "failed reading the request data, read %v of %v bytes", nrRead, length) return rc, respHeader, err } } rawResp, err := c.sendRateLimitedRequest(method, URL, headers, reqData, logger) if err != nil { return } if logger != nil && logger.IsTraceEnabled() { logger.Tracef("Request: %s %s\n", method, URL) logger.Tracef("Request header: %s\n", headers) logger.Tracef("Request body: %s\n", reqData) logger.Tracef("Response: %s\n", rawResp.Status) logger.Tracef("Response header: %s\n", rawResp.Header) logger.Tracef("Response body: %s\n", rawResp.Body) logger.Tracef("Response error: %s\n", err) } foundStatus := false if len(expectedStatus) == 0 { expectedStatus = []int{http.StatusOK} } for _, status := range expectedStatus { if rawResp.StatusCode == status { foundStatus = true break } } if !foundStatus && len(expectedStatus) > 0 { err = handleError(URL, rawResp) rawResp.Body.Close() return } return rawResp.Body, &rawResp.Header, err }
func prepareOrGetContainerInterfaceInfo( api APICalls, machineID string, bridgeDevice string, allocateOrMaintain bool, enableNAT bool, startingNetworkInfo []network.InterfaceInfo, log loggo.Logger, providerType string, ) ([]network.InterfaceInfo, error) { maintain := !allocateOrMaintain if environs.AddressAllocationEnabled(providerType) { if maintain { log.Debugf("running maintenance for container %q", machineID) } else { log.Debugf("trying to allocate static IP for container %q", machineID) } allocatedInfo, err := configureContainerNetwork( machineID, bridgeDevice, api, startingNetworkInfo, allocateOrMaintain, enableNAT, ) if err != nil && !maintain { log.Infof("not allocating static IP for container %q: %v", machineID, err) } return allocatedInfo, err } if maintain { log.Debugf("address allocation disabled: Not running maintenance for machine %q", machineID) return nil, nil } log.Debugf("address allocation feature flag not enabled; using multi-bridge networking for container %q", machineID) // In case we're running on MAAS 1.8+ with devices support, we'll still // call PrepareContainerInterfaceInfo(), but we'll ignore a NotSupported // error if we get it (which means we're not using MAAS 1.8+). containerTag := names.NewMachineTag(machineID) preparedInfo, err := api.PrepareContainerInterfaceInfo(containerTag) if err != nil && errors.IsNotSupported(err) { log.Warningf("new container %q not registered as device: not running on MAAS 1.8+", machineID) return nil, nil } else if err != nil { return nil, errors.Trace(err) } log.Tracef("PrepareContainerInterfaceInfo returned %+v", preparedInfo) dnsServersFound := false for _, info := range preparedInfo { if len(info.DNSServers) > 0 { dnsServersFound = true break } } if !dnsServersFound { logger.Warningf("no DNS settings found, discovering the host settings") dnsServers, searchDomain, err := localDNSServers() if err != nil { return nil, errors.Trace(err) } // Since the result is sorted, the first entry is the primary NIC. preparedInfo[0].DNSServers = dnsServers preparedInfo[0].DNSSearchDomains = []string{searchDomain} logger.Debugf( "setting DNS servers %+v and domains %+v on container interface %q", preparedInfo[0].DNSServers, preparedInfo[0].DNSSearchDomains, preparedInfo[0].InterfaceName, ) } return preparedInfo, nil }
func (*loggerSuite) TestRootLogger(c *gc.C) { root := loggo.Logger{} c.Assert(root.Name(), gc.Equals, "<root>") c.Assert(root.IsErrorEnabled(), gc.Equals, true) c.Assert(root.IsWarningEnabled(), gc.Equals, true) c.Assert(root.IsInfoEnabled(), gc.Equals, false) c.Assert(root.IsDebugEnabled(), gc.Equals, false) c.Assert(root.IsTraceEnabled(), gc.Equals, false) }
// LoggedErrorf logs the error and return an error with the same text. func LoggedErrorf(logger loggo.Logger, format string, a ...interface{}) error { logger.Logf(loggo.ERROR, format, a...) return fmt.Errorf(format, a...) }
func logAllSeverities(logger loggo.Logger) { logger.Criticalf("something critical") logger.Errorf("an error") logger.Warningf("a warning message") logger.Infof("an info message") logger.Debugf("a debug message") logger.Tracef("a trace message") }
func prepareOrGetContainerInterfaceInfo( api APICalls, machineID string, bridgeDevice string, allocateOrMaintain bool, enableNAT bool, startingNetworkInfo []network.InterfaceInfo, log loggo.Logger, ) ([]network.InterfaceInfo, error) { maintain := !allocateOrMaintain if environs.AddressAllocationEnabled() { if maintain { log.Debugf("running maintenance for container %q", machineID) } else { log.Debugf("trying to allocate static IP for container %q", machineID) } allocatedInfo, err := configureContainerNetwork( machineID, bridgeDevice, api, startingNetworkInfo, allocateOrMaintain, enableNAT, ) if err != nil && !maintain { log.Infof("not allocating static IP for container %q: %v", machineID, err) } return allocatedInfo, err } if maintain { log.Debugf("address allocation disabled: Not running maintenance for machine %q", machineID) return nil, nil } log.Debugf("address allocation feature flag not enabled; using DHCP for container %q", machineID) // In case we're running on MAAS 1.8+ with devices support, we'll still // call PrepareContainerInterfaceInfo(), but we'll ignore a NotSupported // error if we get it (which means we're not using MAAS 1.8+). containerTag := names.NewMachineTag(machineID) preparedInfo, err := api.PrepareContainerInterfaceInfo(containerTag) if err != nil && errors.IsNotSupported(err) { log.Warningf("new container %q not registered as device: not running on MAAS 1.8+", machineID) return nil, nil } else if err != nil { return nil, errors.Trace(err) } dnsServers, searchDomain, dnsErr := localDNSServers() if dnsErr != nil { return nil, errors.Trace(dnsErr) } for i, _ := range preparedInfo { preparedInfo[i].DNSServers = dnsServers preparedInfo[i].DNSSearch = searchDomain } log.Tracef("PrepareContainerInterfaceInfo returned %#v", preparedInfo) // Most likely there will be only one item in the list, but check // all of them for forward compatibility. macAddresses := set.NewStrings() for _, prepInfo := range preparedInfo { macAddresses.Add(prepInfo.MACAddress) } log.Infof( "new container %q registered as a MAAS device with MAC address(es) %v", machineID, macAddresses.SortedValues(), ) return preparedInfo, nil }
func (e cleanupErrors) Log(logger loggo.Logger) { logger.Errorf(e.Error()) for _, err := range e.Errors { logger.Errorf(err.Error()) } }