Skip to content

Commit 2d13999

Browse files
feat(logging): Add structured JSON logging support for console (#1265)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent 42c9e28 commit 2d13999

5 files changed

Lines changed: 33 additions & 19 deletions

File tree

contrib/analytics/ivre_api/ivre_api.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@
3636
import logging
3737
from pprint import pformat
3838

39-
from ivre.db import db
40-
from ivre.utils import encode_b64
41-
4239
from core.analytics import InlineAnalytics, OneShotAnalytics
43-
from core.errors import ObservableValidationError
4440
from core.observables import (
4541
AutonomousSystem,
4642
Certificate,
@@ -51,6 +47,10 @@
5147
Text,
5248
Url,
5349
)
50+
from ivre.db import db
51+
from ivre.utils import encode_b64
52+
53+
from core.errors import ObservableValidationError
5454

5555
LOG = logging.getLogger("Yeti-Ivre")
5656

contrib/feeds/otx/otx.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
from datetime import timedelta
22

33
import dateutil.parser
4+
from core.feed import Feed
5+
from core.observables import Email, Hash, Hostname, Ip, Url
46
from mongoengine import DictField
57
from OTXv2 import OTXv2
68

79
from core.config.config import yeti_config
8-
from core.feed import Feed
9-
from core.observables import Email, Hash, Hostname, Ip, Url
1010

1111
OBSERVABLE_TYPES = {
1212
"IPv4": Ip,

contrib/feeds/proofpoint/proofpoint.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77

88
import hammock
99
import requests
10+
from core.entities import TTP, Actor, Campaign
11+
from core.entities.malware import Malware
12+
from core.feed import Feed
13+
from core.observables import Email, File, Hash, Hostname, Ip, Observable, Tag, Text, Url
1014
from mongoengine.errors import DoesNotExist
1115
from requests import auth
1216

1317
from core.config.config import yeti_config
14-
from core.entities import TTP, Actor, Campaign
15-
from core.entities.malware import Malware
1618
from core.errors import ObservableValidationError
17-
from core.feed import Feed
18-
from core.observables import Email, File, Hash, Hostname, Ip, Observable, Tag, Text, Url
1919

2020
log = logging.getLogger("pp2yeti")
2121

contrib/feeds/threattracking/threattracking.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
import hammock
77
import requests
88
import simplejson as json
9+
from core.entities import Actor, Campaign, Malware
10+
from core.feed import Feed
911
from mongoengine.errors import DoesNotExist
1012

1113
from core.config.config import yeti_config
12-
from core.entities import Actor, Campaign, Malware
13-
from core.feed import Feed
1414

1515
# # add configuration to yeti.conf
1616
# [threattracking]

core/logger.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,30 @@ def __init__(self):
6969
def format(self, record):
7070
json_record = {}
7171
json_record["message"] = record.getMessage()
72+
json_record["severity"] = record.levelname
73+
json_record["timestamp"] = datetime.datetime.fromtimestamp(
74+
record.created, datetime.timezone.utc
75+
).isoformat()
76+
json_record["logger"] = record.name
7277
if "username" in record.__dict__:
7378
json_record["username"] = record.__dict__["username"]
7479
if "path" in record.__dict__:
7580
json_record["path"] = record.__dict__["path"]
7681
if "method" in record.__dict__:
7782
json_record["method"] = record.__dict__["method"]
7883
if "body" in record.__dict__ and record.__dict__["body"]:
79-
if record.__dict__["content-type"] == "application/json":
80-
json_record["body"] = json.loads(
81-
record.__dict__["body"].decode("utf-8")
82-
)
83-
else:
84-
json_record["body"] = record.__dict__["body"].decode("utf-8")
84+
try:
85+
body_content = record.__dict__["body"]
86+
if isinstance(body_content, bytes):
87+
body_content = body_content.decode("utf-8")
88+
89+
if record.__dict__.get("content-type") == "application/json":
90+
json_record["body"] = json.loads(body_content)
91+
else:
92+
json_record["body"] = body_content
93+
except Exception:
94+
json_record["body"] = str(record.__dict__["body"])
95+
8596
if "client" in record.__dict__:
8697
json_record["client"] = record.__dict__["client"]
8798
if "status_code" in record.__dict__:
@@ -149,7 +160,10 @@ def filter(self, record):
149160

150161
console_handler = logging.StreamHandler()
151162
console_handler.addFilter(LogFilter())
152-
console_handler.setFormatter(logging.Formatter(log_format))
163+
if os.environ.get("YETI_K8S_RUNTIME", "false").lower() == "true":
164+
console_handler.setFormatter(JsonFormatter())
165+
else:
166+
console_handler.setFormatter(logging.Formatter(log_format))
153167
handlers.append(console_handler)
154168

155169
audit_logfile = yeti_config.get("system", "audit_logfile")

0 commit comments

Comments
 (0)