func (s *PathsSuite) TestWorkerPathsWindows(c *gc.C) { s.PatchValue(&os.HostOS, func() os.OSType { return os.Windows }) dataDir := c.MkDir() unitTag := names.NewUnitTag("some-service/323") worker := "some-worker" paths := uniter.NewWorkerPaths(dataDir, unitTag, worker) relData := relPathFunc(dataDir) relAgent := relPathFunc(relData("agents", "unit-some-service-323")) c.Assert(paths, jc.DeepEquals, uniter.Paths{ ToolsDir: relData("tools/unit-some-service-323"), Runtime: uniter.RuntimePaths{ JujuRunSocket: `\\.\pipe\unit-some-service-323-some-worker-run`, JujucServerSocket: `\\.\pipe\unit-some-service-323-some-worker-agent`, }, State: uniter.StatePaths{ BaseDir: relAgent(), CharmDir: relAgent("charm"), OperationsFile: relAgent("state", "uniter"), RelationsDir: relAgent("state", "relations"), BundlesDir: relAgent("state", "bundles"), DeployerDir: relAgent("state", "deployer"), StorageDir: relAgent("state", "storage"), MetricsSpoolDir: relAgent("state", "spool", "metrics"), }, }) }
func (w *collect) do() error { logger.Tracef("recording metrics") config := w.agent.CurrentConfig() tag := config.Tag() unitTag, ok := tag.(names.UnitTag) if !ok { return errors.Errorf("expected a unit tag, got %v", tag) } paths := uniter.NewWorkerPaths(config.DataDir(), unitTag, "metrics-collect") recorder, err := newRecorder(unitTag, paths, w.unitCharmLookup, w.metricFactory) if errors.Cause(err) == errMetricsNotDefined { logger.Tracef("%v", err) return nil } else if err != nil { return errors.Annotate(err, "failed to instantiate metric recorder") } ctx := newHookContext(unitTag.String(), recorder) err = ctx.addJujuUnitsMetric() if err != nil { return errors.Annotatef(err, "error adding 'juju-units' metric") } r := runner.NewRunner(ctx, paths) err = r.RunHook(string(hooks.CollectMetrics)) if err != nil { return errors.Annotatef(err, "error running 'collect-metrics' hook") } return nil }
// Do satisfies the worker.PeriodWorkerCall function type. func (w *collect) Do(stop <-chan struct{}) error { config := w.agent.CurrentConfig() tag := config.Tag() unitTag, ok := tag.(names.UnitTag) if !ok { return errors.Errorf("expected a unit tag, got %v", tag) } paths := uniter.NewWorkerPaths(config.DataDir(), unitTag, "metrics-collect") recorder, err := newRecorder(unitTag, paths, w.metricFactory) if errors.Cause(err) == errMetricsNotDefined { logger.Tracef("%v", err) return nil } else if err != nil { return errors.Annotate(err, "failed to instantiate metric recorder") } err = w.charmdir.Visit(func() error { return w.runner.do(recorder) }, stop) if err == fortress.ErrAborted { logger.Tracef("cannot execute collect-metrics: %v", err) return nil } return err }
// Manifold creates a metric sender manifold. func Manifold(config ManifoldConfig) dependency.Manifold { return dependency.Manifold{ Inputs: []string{ config.AgentName, config.APICallerName, config.MetricSpoolName, }, Start: func(context dependency.Context) (worker.Worker, error) { var apicaller base.APICaller var factory spool.MetricFactory err := context.Get(config.APICallerName, &apicaller) if err != nil { return nil, errors.Trace(err) } err = context.Get(config.MetricSpoolName, &factory) if err != nil { return nil, errors.Trace(err) } var agent agent.Agent if err := context.Get(config.AgentName, &agent); err != nil { return nil, err } agentConfig := agent.CurrentConfig() tag := agentConfig.Tag() unitTag, ok := tag.(names.UnitTag) if !ok { return nil, errors.Errorf("expected a unit tag, got %v", tag) } paths := uniter.NewWorkerPaths(agentConfig.DataDir(), unitTag, "metrics-send") client := newMetricAdderClient(apicaller) s, err := newSender(client, factory, paths.State.BaseDir, unitTag.String()) if err != nil { return nil, errors.Trace(err) } return spool.NewPeriodicWorker(s.Do, period, worker.NewTimer, s.stop), nil }, } }
func newCollect(config ManifoldConfig, getResource dependency.GetResourceFunc) (*collect, error) { period := defaultPeriod if config.Period != nil { period = *config.Period } var agent agent.Agent if err := getResource(config.AgentName, &agent); err != nil { return nil, err } var metricFactory spool.MetricFactory err := getResource(config.MetricSpoolName, &metricFactory) if err != nil { return nil, err } var charmdir fortress.Guest err = getResource(config.CharmDirName, &charmdir) if err != nil { return nil, err } agentConfig := agent.CurrentConfig() tag := agentConfig.Tag() unitTag, ok := tag.(names.UnitTag) if !ok { return nil, errors.Errorf("expected a unit tag, got %v", tag) } paths := uniter.NewWorkerPaths(agentConfig.DataDir(), unitTag, "metrics-collect") runner := &hookRunner{ unitTag: unitTag.String(), paths: paths, } var listener stopper charmURL, validMetrics, err := readCharm(unitTag, paths) if err != nil { return nil, errors.Trace(err) } if len(validMetrics) > 0 && charmURL.Schema == "local" { h := newHandler(handlerConfig{ unitTag: unitTag, charmURL: charmURL, validMetrics: validMetrics, metricsFactory: metricFactory, runner: runner, }) listener, err = newSocketListener(socketName(paths.State.BaseDir, unitTag.String()), h) if err != nil { return nil, err } } collector := &collect{ period: period, agent: agent, metricFactory: metricFactory, charmdir: charmdir, listener: listener, runner: runner, } return collector, nil }