Skip to content
This repository has been archived by the owner on Dec 17, 2021. It is now read-only.

Commit

Permalink
adding frequency to all metric data and profile if it is set in conf
Browse files Browse the repository at this point in the history
  • Loading branch information
okuzhel committed Sep 22, 2021
1 parent 98aeaf3 commit edf4fc9
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 13 deletions.
10 changes: 9 additions & 1 deletion splunk_connect_for_snmp_poller/manager/data/event_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@

logger = get_logger(__name__)

"""
You can check how the events for HEC should be formatted here
https://docs.splunk.com/Documentation/Splunk/8.2.2/Data/FormateventsforHTTPEventCollector
"""


class EventBuilder:
def __init__(self) -> None:
Expand All @@ -27,6 +32,9 @@ def __init__(self) -> None:
def add(self, field, part: Any) -> None:
self.data[field.value] = part

def add_fields(self, part: Dict) -> None:
self.data[EventField.FIELDS.value] = part

def is_one_time_walk(self, one_time_flag: bool) -> None:
if one_time_flag:
self.data[EventField.SOURCETYPE.value] = EventType.WALK.value
Expand All @@ -42,7 +50,7 @@ class EventField(Enum):
HOST = "host"
INDEX = "index"
EVENT = "event"
FREQUENCY = "frequency"
FREQUENCY = "freqinseconds"
PROFILE = "profile"
FIELDS = "fields"

Expand Down
20 changes: 19 additions & 1 deletion splunk_connect_for_snmp_poller/manager/data/inventory_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import json
from dataclasses import dataclass

from splunk_connect_for_snmp_poller.manager.data.event_builder import EventField


@dataclass
class InventoryRecord:
Expand All @@ -24,5 +26,21 @@ class InventoryRecord:
profile: str
frequency_str: str

def toJson(self):
def to_json(self) -> str:
return json.dumps(self, default=lambda o: o.__dict__)

def extend_dict_with_provided_data(
self, fields: dict, additional_metric_fields: list
) -> dict:
if (
additional_metric_fields
and EventField.PROFILE.value in additional_metric_fields
):
fields[EventField.PROFILE.value] = self.profile

return fields

@staticmethod
def from_json(ir_json: str):
ir_dict = json.loads(ir_json)
return InventoryRecord(**ir_dict)
35 changes: 29 additions & 6 deletions splunk_connect_for_snmp_poller/manager/hec_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
EventField,
EventType,
)
from splunk_connect_for_snmp_poller.manager.data.inventory_record import InventoryRecord
from splunk_connect_for_snmp_poller.manager.static.mib_enricher import MibEnricher

logger = get_logger(__name__)
Expand All @@ -36,6 +37,8 @@ def post_data_to_splunk_hec(
variables_binds,
is_metric,
index,
ir,
additional_metric_fields,
one_time_flag=False,
mib_enricher=None,
):
Expand All @@ -44,7 +47,13 @@ def post_data_to_splunk_hec(
if is_metric:
logger.debug(f"+++++++++metric index: {index['metric_index']} +++++++++")
post_metric_data(
metrics_endpoint, host, variables_binds, index["metric_index"], mib_enricher
metrics_endpoint,
host,
variables_binds,
index["metric_index"],
ir,
additional_metric_fields,
mib_enricher,
)
else:
logger.debug(f"*********event index: {index['event_index']} ********")
Expand Down Expand Up @@ -86,9 +95,9 @@ def post_event_data(
)


def init_builder_with_common_data(time, host, index) -> EventBuilder:
def init_builder_with_common_data(current_time, host, index) -> EventBuilder:
builder = EventBuilder()
builder.add(EventField.TIME, time)
builder.add(EventField.TIME, current_time)
builder.add(EventField.HOST, host)
builder.add(EventField.INDEX, index)
return builder
Expand Down Expand Up @@ -135,17 +144,31 @@ def _enrich_event_data(mib_enricher: MibEnricher, variables_binds: dict) -> str:
return non_metric_result


def post_metric_data(endpoint, host, variables_binds, index, mib_enricher=None):
def post_metric_data(
endpoint,
host,
variables_binds,
index,
ir: InventoryRecord,
additional_metric_fields,
mib_enricher=None,
):
json_val = json.loads(variables_binds)
metric_name = json_val["metric_name"]
metric_value = json_val["_value"]
fields = {"metric_name:" + metric_name: metric_value}
fields = {
"metric_name:" + metric_name: metric_value,
EventField.FREQUENCY.value: ir.frequency_str,
}
if mib_enricher:
_enrich_metric_data(mib_enricher, json_val, fields)

if additional_metric_fields:
fields = ir.extend_dict_with_provided_data(fields, additional_metric_fields)

builder = init_builder_with_common_data(time.time(), host, index)
builder.add(EventField.EVENT, EventType.METRIC.value)
builder.add(EventField.FIELDS, fields)
builder.add_fields(fields)

data = builder.build()

Expand Down
2 changes: 1 addition & 1 deletion splunk_connect_for_snmp_poller/manager/poller.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,4 @@ def __start_realtime_scheduler_task(self):

def scheduled_task(ir: InventoryRecord, server_config, splunk_indexes):
logger.debug("Executing scheduled_task for %s", ir.__repr__())
snmp_polling.delay(ir.toJson(), server_config, splunk_indexes)
snmp_polling.delay(ir.to_json(), server_config, splunk_indexes)
2 changes: 1 addition & 1 deletion splunk_connect_for_snmp_poller/manager/poller_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def onetime_task(inventory_record: InventoryRecord, server_config, splunk_indexe
logger.debug("Executing onetime_task for %s", inventory_record.__repr__())

snmp_polling.delay(
inventory_record.toJson(),
inventory_record.to_json(),
server_config,
splunk_indexes,
one_time_flag=True,
Expand Down
30 changes: 30 additions & 0 deletions splunk_connect_for_snmp_poller/manager/task_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ async def snmp_get_handler(
otel_logs_url,
otel_metrics_url,
one_time_flag,
ir,
additional_metric_fields,
var_binds,
):
"""
Expand Down Expand Up @@ -244,6 +246,8 @@ async def snmp_get_handler(
result,
is_metric,
index,
ir,
additional_metric_fields,
one_time_flag,
mib_enricher,
)
Expand Down Expand Up @@ -297,6 +301,8 @@ def _any_walk_failure_happened(
otel_metrics_url,
one_time_flag,
is_metric,
ir,
additional_metric_fields,
varBinds,
):
if errorIndication:
Expand All @@ -309,6 +315,8 @@ def _any_walk_failure_happened(
result,
is_metric,
index,
ir,
additional_metric_fields,
one_time_flag,
)
return True
Expand All @@ -324,6 +332,8 @@ def _any_walk_failure_happened(
result,
is_metric,
index,
ir,
additional_metric_fields,
one_time_flag,
)
return True
Expand All @@ -344,6 +354,8 @@ async def snmp_bulk_handler(
otel_logs_url,
otel_metrics_url,
one_time_flag,
ir,
additional_metric_fields,
var_binds,
):
"""
Expand Down Expand Up @@ -379,6 +391,8 @@ async def snmp_bulk_handler(
result,
is_metric,
index,
ir,
additional_metric_fields,
one_time_flag,
mib_enricher,
)
Expand All @@ -396,6 +410,8 @@ async def walk_handler(
otel_logs_url,
otel_metrics_url,
one_time_flag,
ir,
additional_metric_fields,
):
"""
Perform the SNMP Walk for oid end with *,
Expand All @@ -422,6 +438,8 @@ async def walk_handler(
otel_metrics_url,
one_time_flag,
is_metric,
ir,
additional_metric_fields,
varBinds,
):
break
Expand All @@ -434,6 +452,8 @@ async def walk_handler(
result,
is_metric,
index,
ir,
additional_metric_fields,
one_time_flag,
)

Expand All @@ -452,6 +472,8 @@ async def walk_handler_with_enricher(
otel_logs_url,
otel_metrics_url,
one_time_flag,
ir,
additional_metric_fields,
):
"""
Perform the SNMP Walk for oid end with *,
Expand All @@ -478,6 +500,8 @@ async def walk_handler_with_enricher(
index,
otel_logs_url,
otel_metrics_url,
ir,
additional_metric_fields,
one_time_flag,
is_metric,
varBinds,
Expand Down Expand Up @@ -511,6 +535,8 @@ async def walk_handler_with_enricher(
otel_metrics_url,
index,
one_time_flag,
ir,
additional_metric_fields,
mib_enricher,
]
_post_walk_data_to_splunk(
Expand Down Expand Up @@ -579,6 +605,8 @@ def _post_walk_data_to_splunk(
otel_metrics_url,
index,
one_time_flag,
ir,
additional_metric_fields,
mib_enricher,
):
for result in result_list:
Expand All @@ -589,6 +617,8 @@ def _post_walk_data_to_splunk(
result,
is_metric,
index,
ir,
additional_metric_fields,
one_time_flag,
mib_enricher,
)
Expand Down
11 changes: 8 additions & 3 deletions splunk_connect_for_snmp_poller/manager/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
import json
import os
import threading

Expand Down Expand Up @@ -64,6 +63,8 @@ async def get_snmp_data(
otel_logs_url,
otel_metrics_url,
one_time_flag,
ir,
additional_metric_fields,
):
if var_binds:
try:
Expand All @@ -80,6 +81,8 @@ async def get_snmp_data(
otel_logs_url,
otel_metrics_url,
one_time_flag,
ir,
additional_metric_fields,
var_binds,
)
except Exception as e:
Expand Down Expand Up @@ -117,8 +120,7 @@ def sort_varbinds(varbind_list: list) -> VarbindCollection:
# TODO remove the debugging statement later
@app.task
def snmp_polling(ir_json: str, server_config, index, one_time_flag=False):
ir_dict = json.loads(ir_json)
ir = InventoryRecord(**ir_dict)
ir = InventoryRecord.from_json(ir_json)

async_to_sync(snmp_polling_async)(ir, server_config, index, one_time_flag)

Expand Down Expand Up @@ -146,6 +148,7 @@ async def snmp_polling_async(
logger.debug("==========context_data=========\n%s", context_data)

mongo_connection = WalkedHostsRepository(server_config["mongo"])
additional_metric_fields = server_config.get("additionalMetricField")
enricher_presence = "enricher" in server_config
static_parameters = [
snmp_engine,
Expand All @@ -158,6 +161,8 @@ async def snmp_polling_async(
otel_logs_url,
otel_metrics_url,
one_time_flag,
ir,
additional_metric_fields,
]
get_bulk_specific_parameters = [mongo_connection, enricher_presence]

Expand Down
25 changes: 25 additions & 0 deletions tests/data/test_event_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,28 @@ def test_event_build_for_walk_event(self):
builder.is_one_time_walk(True)

self.assertDictEqual(expected, builder.build())

def test_event_build_with_added_fields(self):
"""
Test that checks if EventBuilder correctly builds dict with fields
"""
timer = time.time()
some_field_ = {"some": "field"}
expected = {
"time": timer,
"sourcetype": "sc4snmp:meta",
"host": "ourhost",
"index": "meta_index",
"event": "binds",
"fields": some_field_,
}

builder = EventBuilder()
builder.add(EventField.TIME, timer)
builder.add(EventField.HOST, "ourhost")
builder.add(EventField.INDEX, "meta_index")
builder.add(EventField.SOURCETYPE, "sc4snmp:meta")
builder.add(EventField.EVENT, "binds")
builder.add_fields(some_field_)

self.assertDictEqual(expected, builder.build())
Loading

0 comments on commit edf4fc9

Please sign in to comment.