Skip to content

Commit

Permalink
feat: add transform to field details
Browse files Browse the repository at this point in the history
  • Loading branch information
victorhos committed Sep 21, 2023
1 parent 79ce612 commit 2e65ded
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,6 @@ build-iPhoneSimulator/
# .rubocop-https?--*

# End of https://www.gitignore.io/api/ruby,python,intellij+all

# Vim
*.swp
81 changes: 81 additions & 0 deletions tests/integration/fluentd/test_dynatrace_3th_file_configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from datetime import datetime
from uuid import uuid4

import pytest
from faker import Faker

from python_fluentd_testing.fluentd_evaluator import FluentdEvaluator
from tests.resources.support import absolute_path_fluentd_output_file
from tests.resources.support import try_to_remove_key_otherwise_return_it


@pytest.fixture
def setup_fluentd_scenario_3():
folder_location, abs_file_path = absolute_path_fluentd_output_file("fluent-dynatrace-output-3.log")
with FluentdEvaluator(
"fluent-dynatrace-3.conf", folder_location, abs_file_path, 24232
).initialize_fluent_daemon() as f:
yield f


def test_should_emit_and_transform_content_and_body_keys_to_send_to_dynatrace(setup_fluentd_scenario_3):
# Arrange
sample_stream_payload = [
{
"log_id": "90020221124231024915274964892613219266671587159978278962",
"data": {
"date": "2022-11-24T23:10:23.560Z",
"type": "fp",
"description": "Wrong email or password.",
"connection": "jsm-main-including-migrations",
"connection_id": "con_DtzeqpeWHFrePk99",
"client_id": "DMx4w5HbYCCWzAXRxZmK2pPJMyXzYPjx",
"client_name": "Loja Virtual",
"ip": "2804:14d:1a87:cf49::9311",
"user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
"details": {
"error": {
"message": "Wrong email or password."
},
"request": {
"method": "requestOptions",
"path": "requestOptions",
},
"response": {
"body": "httpResponseBody",
"statusCode": "httpResponseStatusCode",
},
},
"user_id": "auth0|45f28abf-e4d6-4001-a29a-0a00a38e87b2",
"user_name": "[email protected]",
"strategy": "auth0",
"strategy_type": "database",
"log_id": "90020221124231024915274964892613219266671587159978278962",
},
}
]
# Act
result = setup_fluentd_scenario_3.emit_it_through_http_post_and_get_computed_result(sample_stream_payload)
# Assert
cleaned_result = try_to_remove_key_otherwise_return_it(result, "tag")
# https://www.dynatrace.com/support/help/dynatrace-api/environment-api/log-monitoring-v2/post-ingest-logs
# Content. If the content key is not set, the whole JSON is parsed as the content.
auth0_event = sample_stream_payload[0]["data"]
expected_namespace = f'{auth0_event["strategy"]}|{auth0_event["strategy_type"]}|{auth0_event["connection"]}'
assert cleaned_result == {
"content": "Wrong email or password.",
"body": {
"error": {"message": "Wrong email or password."},
"request": {"method": "requestOptions", "path": "requestOptions"},
"response": {"body": "httpResponseBody", "statusCode": "httpResponseStatusCode"}
},
"date": auth0_event["date"],
"severity": "alert",
"service.name": "auth0",
"service.namespace": expected_namespace,
"audit.action": auth0_event["type"],
"audit.identity": auth0_event["user_id"],
"audit.result": auth0_event["details"]["error"]["message"],
"trace_id": sample_stream_payload[0]["log_id"],
"log.source": "fluentd",
}
81 changes: 81 additions & 0 deletions tests/resources/fluentd-setup/fluentd/etc/fluent-dynatrace-3.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<source>
@type http
port 24232
bind 0.0.0.0
</source>

<filter jsm.*>
type split_array
</filter>

<match jsm.*>
@type rewrite_tag_filter
<rule>
key $.data.type
pattern /^du|f|fapi|fc|fce|fco|fcoa|fcp|fcph|fcpn|fcpr|fcpro|fcu|fd|fdeac|fdeaz|fdecc|fdu|feacft|feccft|fede|fens|feoobft|feotpft|fepft|fepotpft|fercft|fertft|ferrt|fi|flo|fn|fp|fs|fsa|fu|fui|fv|fvr|gd_auth_failed|gd_otp_rate_limit_exceed|gd_recovery_rate_limit_exceed|gd_send_sms_failure|gd_send_voice_failure|gd_start_enroll_failed|gd_webauthn_enrollment_failed$/
tag alert.label.jsm
</rule>
<rule>
# Catch all rule so it does not drop the record
key $.data.type
pattern .*
tag unknown.label.jsm
</rule>
</match>

<filter alert.label.jsm>
@type record_modifier
<record>
severity 'alert'
</record>
</filter>

<filter **.jsm.**>
@type record_modifier
remove_keys _dummy_
<record>
_dummy_ ${if record['data'].has_key?('description'); record['content'] = record['data']['description']; elsif record['data'].has_key?('details') and record['data']['details'].has_key?('error') and record['data']['details']['error'].has_key?('message'); record['content'] = record['data']['details']['error']['message']; else record['content'] = 'N/A'; end; nil}
</record>
</filter>

<filter **.jsm.**>
@type record_modifier
remove_keys _dummy_
<record>
_dummy_ ${if record['data'].has_key?('details'); record['detail'] = record['data']['details']; else record['detail'] = 'N/A'; end; nil}
</record>
</filter>

<filter **.jsm.**>
@type record_transformer
enable_ruby
renew_record
<record>
body ${record["detail"]}
content ${record["content"]}
date ${record["data"]["date"]}
severity ${record["severity"]}
service.name 'auth0'
service.namespace ${record["data"]["strategy"]}|${record["data"]["strategy_type"]}|${record["data"]["connection"]}
audit.action ${record["data"]["type"]}
audit.identity ${record["data"]["user_id"]}
audit.result ${record["data"]["details"]["error"]["message"]}
trace_id ${record["log_id"]}
log.source 'fluentd'
</record>
</filter>

<match **.jsm.**>
@type file
path /result/fluent-dynatrace-output-3.log
append true
add_path_suffix false
<format>
@type json
</format>
<buffer []>
@type memory
chunk_limit_records 1
retry_max_times 0
</buffer>
</match>

0 comments on commit 2e65ded

Please sign in to comment.