From 606f961a6d144e6237fd15cf7c5a17f41da90361 Mon Sep 17 00:00:00 2001 From: Nicolas Ruflin Date: Mon, 9 Jul 2018 11:02:24 +0200 Subject: [PATCH] Refactor module state reporting to be reusable (#7536) This makes the state reporting reusable for Filebeat modules and inputs. --- auditbeat/module/auditd/show_linux.go | 17 +++++++ libbeat/monitoring/list.go | 72 +++++++++++++++++++++++++++ metricbeat/mb/module/runner.go | 44 ++-------------- 3 files changed, 94 insertions(+), 39 deletions(-) create mode 100644 libbeat/monitoring/list.go diff --git a/auditbeat/module/auditd/show_linux.go b/auditbeat/module/auditd/show_linux.go index 948e70922ca..f7ce49fdce0 100644 --- a/auditbeat/module/auditd/show_linux.go +++ b/auditbeat/module/auditd/show_linux.go @@ -1,3 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package auditd import ( diff --git a/libbeat/monitoring/list.go b/libbeat/monitoring/list.go new file mode 100644 index 00000000000..0b00d6dd506 --- /dev/null +++ b/libbeat/monitoring/list.go @@ -0,0 +1,72 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package monitoring + +import ( + "sync" +) + +// UniqueList is used to collect a list of items (strings) and get the total count and all unique strings. +type UniqueList struct { + sync.Mutex + list map[string]int +} + +// NewUniqueList create a new UniqueList +func NewUniqueList() *UniqueList { + return &UniqueList{ + list: map[string]int{}, + } +} + +// Add adds an item to the list and increases the count for it. +func (l *UniqueList) Add(item string) { + l.Lock() + defer l.Unlock() + l.list[item]++ +} + +// Remove removes and item for the list and decreases the count. +func (l *UniqueList) Remove(item string) { + l.Lock() + defer l.Unlock() + l.list[item]-- +} + +// Report can be used as reporting function for monitoring. +// It reports a total count value and a names array with all the items. +func (l *UniqueList) Report(m Mode, V Visitor) { + V.OnRegistryStart() + defer V.OnRegistryFinished() + + var items []string + var count int64 + + l.Lock() + defer l.Unlock() + + for key, val := range l.list { + if val > 0 { + items = append(items, key) + } + count += int64(val) + } + + ReportInt(V, "count", count) + ReportStringSlice(V, "names", items) +} diff --git a/metricbeat/mb/module/runner.go b/metricbeat/mb/module/runner.go index 07c8ad877a4..84f24dec62b 100644 --- a/metricbeat/mb/module/runner.go +++ b/metricbeat/mb/module/runner.go @@ -26,13 +26,12 @@ import ( ) var ( - moduleList map[string]int - moduleListLock sync.Mutex + moduleList *monitoring.UniqueList ) func init() { - moduleList = map[string]int{} - monitoring.NewFunc(monitoring.GetNamespace("state").GetRegistry(), "module", reportModules, monitoring.Report) + moduleList = monitoring.NewUniqueList() + monitoring.NewFunc(monitoring.GetNamespace("state").GetRegistry(), "module", moduleList.Report, monitoring.Report) } // Runner is a facade for a Wrapper that provides a simple interface @@ -72,7 +71,7 @@ func (mr *runner) Start() { mr.startOnce.Do(func() { output := mr.mod.Start(mr.done) mr.wg.Add(1) - addModule(mr.mod.Name()) + moduleList.Add(mr.mod.Name()) go func() { defer mr.wg.Done() PublishChannels(mr.client, output) @@ -85,43 +84,10 @@ func (mr *runner) Stop() { close(mr.done) mr.client.Close() mr.wg.Wait() - removeModule(mr.mod.Name()) + moduleList.Remove(mr.mod.Name()) }) } func (mr *runner) String() string { return fmt.Sprintf("%s [metricsets=%d]", mr.mod.Name(), len(mr.mod.metricSets)) } - -func addModule(module string) { - moduleListLock.Lock() - defer moduleListLock.Unlock() - moduleList[module]++ -} - -func removeModule(module string) { - moduleListLock.Lock() - defer moduleListLock.Unlock() - moduleList[module]-- -} - -func reportModules(m monitoring.Mode, V monitoring.Visitor) { - V.OnRegistryStart() - defer V.OnRegistryFinished() - - var modules []string - var count int64 - - moduleListLock.Lock() - defer moduleListLock.Unlock() - - for key, val := range moduleList { - if val > 0 { - modules = append(modules, key) - } - count += int64(val) - } - - monitoring.ReportInt(V, "count", count) - monitoring.ReportStringSlice(V, "names", modules) -}