Example #1
0
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())
}
Example #2
0
File: broker.go Project: bac/juju
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,
		)
	}
}
Example #3
0
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,
		)
	}
}
Example #4
0
// 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
}
Example #5
0
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)
}
Example #6
0
// 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
}
Example #7
0
File: broker.go Project: bac/juju
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
}
Example #8
0
File: tracing.go Project: bac/juju
// 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)
		})
	}
}
Example #9
0
File: tracing.go Project: bac/juju
// 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)
		})
	}
}
Example #10
0
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)
}
Example #11
0
// 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
}
Example #12
0
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
}
Example #13
0
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)
}
Example #14
0
// 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...)
}
Example #15
0
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")
}
Example #16
0
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
}
Example #17
0
func (e cleanupErrors) Log(logger loggo.Logger) {
	logger.Errorf(e.Error())
	for _, err := range e.Errors {
		logger.Errorf(err.Error())
	}
}