// HookContext is part of the ContextFactory interface. func (f *contextFactory) HookContext(hookInfo hook.Info) (*HookContext, error) { ctx, err := f.coreContext() if err != nil { return nil, errors.Trace(err) } hookName := string(hookInfo.Kind) if hookInfo.Kind.IsRelation() { ctx.relationId = hookInfo.RelationId ctx.remoteUnitName = hookInfo.RemoteUnit relation, found := ctx.relations[hookInfo.RelationId] if !found { return nil, errors.Errorf("unknown relation id: %v", hookInfo.RelationId) } if hookInfo.Kind == hooks.RelationDeparted { relation.cache.RemoveMember(hookInfo.RemoteUnit) } else if hookInfo.RemoteUnit != "" { // Clear remote settings cache for changing remote unit. relation.cache.InvalidateMember(hookInfo.RemoteUnit) } hookName = fmt.Sprintf("%s-%s", relation.Name(), hookInfo.Kind) } if hookInfo.Kind.IsStorage() { ctx.storageTag = names.NewStorageTag(hookInfo.StorageId) if _, found := ctx.storage.Storage(ctx.storageTag); !found { return nil, errors.Errorf("unknown storage id: %v", hookInfo.StorageId) } storageName, err := names.StorageName(hookInfo.StorageId) if err != nil { return nil, errors.Trace(err) } hookName = fmt.Sprintf("%s-%s", storageName, hookName) } // Metrics are only sent from the collect-metrics hook. if hookInfo.Kind == hooks.CollectMetrics { ch, err := getCharm(f.paths.GetCharmDir()) if err != nil { return nil, errors.Trace(err) } ctx.definedMetrics = ch.Metrics() chURL, err := f.unit.CharmURL() if err != nil { return nil, errors.Trace(err) } charmMetrics := map[string]charm.Metric{} if ch.Metrics() != nil { charmMetrics = ch.Metrics().Metrics } ctx.metricsRecorder, err = metrics.NewJSONMetricRecorder( f.paths.GetMetricsSpoolDir(), charmMetrics, chURL.String()) if err != nil { return nil, errors.Trace(err) } } ctx.id = f.newId(hookName) return ctx, nil }
func (s *MetricsReaderSuite) SetUpTest(c *gc.C) { s.paths = newTestPaths(c) var err error s.w, err = metrics.NewJSONMetricRecorder( s.paths.GetMetricsSpoolDir(), map[string]corecharm.Metric{"pings": corecharm.Metric{}}, "local:precise/wordpress") c.Assert(err, jc.ErrorIsNil) err = s.w.AddMetric("pings", "5", time.Now()) c.Assert(err, jc.ErrorIsNil) err = s.w.Close() c.Assert(err, jc.ErrorIsNil) }
func (s *MetricsRecorderSuite) TestUnknownMetricKey(c *gc.C) { w, err := metrics.NewJSONMetricRecorder(s.paths.GetMetricsSpoolDir(), map[string]corecharm.Metric{}, "local:precise/wordpress") c.Assert(err, jc.ErrorIsNil) c.Assert(w, gc.NotNil) err = w.AddMetric("pings", "5", time.Now()) c.Assert(err, gc.ErrorMatches, `metric key "pings" not declared by the charm`) err = w.Close() c.Assert(err, jc.ErrorIsNil) r, err := metrics.NewJSONMetricReader(s.paths.GetMetricsSpoolDir()) c.Assert(err, jc.ErrorIsNil) batches, err := r.Read() c.Assert(err, jc.ErrorIsNil) c.Assert(batches, gc.HasLen, 0) }
func (s *MetricsOperationSuite) SetUpTest(c *gc.C) { s.spoolDir = c.MkDir() declaredMetrics := map[string]corecharm.Metric{ "pings": corecharm.Metric{Description: "test pings", Type: corecharm.MetricTypeAbsolute}, } recorder, err := metrics.NewJSONMetricRecorder(s.spoolDir, declaredMetrics, "local:trusty/testcharm") c.Assert(err, jc.ErrorIsNil) err = recorder.AddMetric("pings", "50", time.Now()) c.Assert(err, jc.ErrorIsNil) err = recorder.Close() c.Assert(err, jc.ErrorIsNil) }
func (s addMetrics) step(c *gc.C, ctx *context) { var declaredMetrics map[string]corecharm.Metric if ctx.sch.Metrics() != nil { declaredMetrics = ctx.sch.Metrics().Metrics } spoolDir := filepath.Join(ctx.path, "state", "spool", "metrics") recorder, err := metrics.NewJSONMetricRecorder(spoolDir, declaredMetrics, ctx.sch.URL().String()) c.Assert(err, jc.ErrorIsNil) for _, value := range s.values { recorder.AddMetric("pings", value, time.Now()) } err = recorder.Close() c.Assert(err, jc.ErrorIsNil) }
func (s *MetricsRecorderSuite) TestInit(c *gc.C) { w, err := metrics.NewJSONMetricRecorder(s.paths.GetMetricsSpoolDir(), map[string]corecharm.Metric{"pings": corecharm.Metric{}}, "local:precise/wordpress") c.Assert(err, jc.ErrorIsNil) c.Assert(w, gc.NotNil) err = w.AddMetric("pings", "5", time.Now()) c.Assert(err, jc.ErrorIsNil) err = w.Close() c.Assert(err, jc.ErrorIsNil) r, err := metrics.NewJSONMetricReader(s.paths.GetMetricsSpoolDir()) c.Assert(err, jc.ErrorIsNil) batches, err := r.Read() c.Assert(err, jc.ErrorIsNil) c.Assert(batches, gc.HasLen, 1) batch := batches[0] c.Assert(batch.CharmURL, gc.Equals, "local:precise/wordpress") c.Assert(batch.UUID, gc.Not(gc.Equals), "") c.Assert(batch.Metrics, gc.HasLen, 1) c.Assert(batch.Metrics[0].Key, gc.Equals, "pings") c.Assert(batch.Metrics[0].Value, gc.Equals, "5") err = r.Close() c.Assert(err, jc.ErrorIsNil) }
func NewHookContext( unit *uniter.Unit, state *uniter.State, id, uuid, envName string, relationId int, remoteUnitName string, relations map[int]*ContextRelation, apiAddrs []string, serviceOwner names.UserTag, proxySettings proxy.Settings, canAddMetrics bool, charmMetrics *charm.Metrics, actionData *ActionData, assignedMachineTag names.MachineTag, paths Paths, ) (*HookContext, error) { ctx := &HookContext{ unit: unit, state: state, id: id, uuid: uuid, envName: envName, unitName: unit.Name(), relationId: relationId, remoteUnitName: remoteUnitName, relations: relations, apiAddrs: apiAddrs, serviceOwner: serviceOwner, proxySettings: proxySettings, metricsRecorder: nil, definedMetrics: charmMetrics, actionData: actionData, pendingPorts: make(map[PortRange]PortRangeInfo), assignedMachineTag: assignedMachineTag, } if canAddMetrics { charmURL, err := unit.CharmURL() if err != nil { return nil, err } ctx.metricsRecorder, err = metrics.NewJSONMetricRecorder( paths.GetMetricsSpoolDir(), charmMetrics.Metrics, charmURL.String()) if err != nil { return nil, err } } // Get and cache the addresses. var err error ctx.publicAddress, err = unit.PublicAddress() if err != nil && !params.IsCodeNoAddressSet(err) { return nil, err } ctx.privateAddress, err = unit.PrivateAddress() if err != nil && !params.IsCodeNoAddressSet(err) { return nil, err } ctx.availabilityzone, err = unit.AvailabilityZone() if err != nil { return nil, err } ctx.machinePorts, err = state.AllMachinePorts(ctx.assignedMachineTag) if err != nil { return nil, errors.Trace(err) } statusCode, statusInfo, err := unit.MeterStatus() if err != nil { return nil, errors.Annotate(err, "could not retrieve meter status for unit") } ctx.meterStatus = &meterStatus{ code: statusCode, info: statusInfo, } return ctx, nil }