Skip to content

Commit 051e6ac

Browse files
[executors] feat: add google cloud logging option
1 parent ac2b623 commit 051e6ac

File tree

10 files changed

+41
-13
lines changed

10 files changed

+41
-13
lines changed

libs/core/garf_core/query_editor.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
from garf_core import query_parser
3030

31+
logger = logging.getLogger(__name__)
32+
3133
QueryParameters: TypeAlias = dict[str, Union[str, float, int, list]]
3234

3335

@@ -126,22 +128,22 @@ class TemplateProcessorMixin:
126128
def replace_params_template(
127129
self, query_text: str, params: GarfQueryParameters | None = None
128130
) -> str:
129-
logging.debug('Original query text:\n%s', query_text)
131+
logger.debug('Original query text:\n%s', query_text)
130132
if params:
131133
if templates := params.template:
132134
query_templates = {
133135
name: value for name, value in templates.items() if name in query_text
134136
}
135137
if query_templates:
136138
query_text = self.expand_jinja(query_text, query_templates)
137-
logging.debug('Query text after jinja expansion:\n%s', query_text)
139+
logger.debug('Query text after jinja expansion:\n%s', query_text)
138140
else:
139141
query_text = self.expand_jinja(query_text, {})
140142
else:
141143
query_text = self.expand_jinja(query_text, {})
142144
if macros := params.macro:
143145
query_text = query_text.format(**macros)
144-
logging.debug('Query text after macro substitution:\n%s', query_text)
146+
logger.debug('Query text after macro substitution:\n%s', query_text)
145147
else:
146148
query_text = self.expand_jinja(query_text, {})
147149
return query_text

libs/executors/garf_executors/entrypoints/cli.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from __future__ import annotations
2121

2222
import argparse
23+
import logging
2324
import sys
2425

2526
from garf_io import reader
@@ -102,6 +103,7 @@ def main():
102103
logger.info('Running queries sequentially')
103104
for query in args.query:
104105
query_executor.execute(reader_client.read(query), query, context)
106+
logging.shutdown()
105107

106108

107109
if __name__ == '__main__':

libs/executors/garf_executors/entrypoints/utils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,15 @@ class GarfParamsException(Exception):
9393
class LoggerEnum(str, enum.Enum):
9494
local = 'local'
9595
rich = 'rich'
96+
gcloud = 'gcloud'
9697

9798

9899
def init_logging(
99100
loglevel: str = 'INFO',
100101
logger_type: str | LoggerEnum = 'local',
101102
name: str = __name__,
102103
) -> logging.Logger:
104+
loglevel = getattr(logging, loglevel)
103105
if logger_type == 'rich':
104106
logging.basicConfig(
105107
format='%(message)s',
@@ -109,6 +111,17 @@ def init_logging(
109111
rich_logging.RichHandler(rich_tracebacks=True),
110112
],
111113
)
114+
elif logger_type == 'gcloud':
115+
import google.cloud.logging as glogging
116+
117+
client = glogging.Client()
118+
handler = glogging.handlers.CloudLoggingHandler(client, name='garf')
119+
handler.close()
120+
glogging.handlers.setup_logging(handler, log_level=loglevel)
121+
logging.basicConfig(
122+
level=loglevel,
123+
handlers=[handler],
124+
)
112125
else:
113126
logging.basicConfig(
114127
format='[%(asctime)s][%(name)s][%(levelname)s] %(message)s',

libs/executors/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ version = {attr = "garf_executors.__version__"}
4040
bq=[
4141
"garf-io[bq]",
4242
"pandas",
43+
"google-cloud-logging",
4344
]
4445
sql=[
4546
"garf-io[sqlalchemy]",

libs/exporters/garf_exporter/exporter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def _define_metrics(
165165
if virtual_columns := query_specification.virtual_columns:
166166
for column, field in virtual_columns.items():
167167
metrics[column] = self._define_gauge(column, suffix, labels)
168-
logging.debug('metrics: %s', metrics)
168+
logger.debug('metrics: %s', metrics)
169169
return metrics
170170

171171
def _define_labels(

libs/io/garf_io/writers/bigquery_writer.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
from garf_io import exceptions, formatter
3939
from garf_io.writers import abs_writer
4040

41+
logger = logging.getLogger(__name__)
42+
4143

4244
class BigQueryWriterError(exceptions.GarfIoError):
4345
"""BigQueryWriter specific errors."""
@@ -136,13 +138,13 @@ def write(self, report: garf_report.GarfReport, destination: str) -> str:
136138
else:
137139
df = report.to_pandas()
138140
df = df.replace({np.nan: None})
139-
logging.debug('Writing %d rows of data to %s', len(df), destination)
141+
logger.debug('Writing %d rows of data to %s', len(df), destination)
140142
job = self.client.load_table_from_dataframe(
141143
dataframe=df, destination=table, job_config=job_config
142144
)
143145
try:
144146
job.result()
145-
logging.debug('Writing to %s is completed', destination)
147+
logger.debug('Writing to %s is completed', destination)
146148
except google_cloud_exceptions.BadRequest as e:
147149
raise ValueError(f'Unable to save data to BigQuery! {str(e)}') from e
148150
return f'[BigQuery] - at {self.dataset_id}.{destination}'

libs/io/garf_io/writers/csv_writer.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
from garf_io import formatter
3131
from garf_io.writers import file_writer
3232

33+
logger = logging.getLogger(__name__)
34+
3335

3436
class CsvWriter(file_writer.FileWriter):
3537
"""Writes Garf Report to CSV.
@@ -83,7 +85,7 @@ def write(self, report: garf_report.GarfReport, destination: str) -> str:
8385
report = self.format_for_write(report)
8486
destination = formatter.format_extension(destination, new_extension='.csv')
8587
self.create_dir()
86-
logging.debug('Writing %d rows of data to %s', len(report), destination)
88+
logger.debug('Writing %d rows of data to %s', len(report), destination)
8789
output_path = pathlib.Path(self.destination_folder) / destination
8890
with smart_open.open(
8991
output_path,
@@ -98,5 +100,5 @@ def write(self, report: garf_report.GarfReport, destination: str) -> str:
98100
)
99101
writer.writerow(report.column_names)
100102
writer.writerows(report.results)
101-
logging.debug('Writing to %s is completed', output_path)
103+
logger.debug('Writing to %s is completed', output_path)
102104
return f'[CSV] - at {output_path}'

libs/io/garf_io/writers/json_writer.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
from garf_io import formatter
2727
from garf_io.writers import file_writer
2828

29+
logger = logging.getLogger(__name__)
30+
2931

3032
class JsonWriter(file_writer.FileWriter):
3133
"""Writes Garf Report to JSON.
@@ -68,9 +70,9 @@ def write(self, report: garf_report.GarfReport, destination: str) -> str:
6870
destination, new_extension=file_extension
6971
)
7072
self.create_dir()
71-
logging.debug('Writing %d rows of data to %s', len(report), destination)
73+
logger.debug('Writing %d rows of data to %s', len(report), destination)
7274
output_path = pathlib.Path(self.destination_folder) / destination
7375
with smart_open.open(output_path, 'w', encoding='utf-8') as f:
7476
f.write(report.to_json(output=self.format))
75-
logging.debug('Writing to %s is completed', output_path)
77+
logger.debug('Writing to %s is completed', output_path)
7678
return f'[JSON] - at {output_path}'

libs/io/garf_io/writers/sheets_writer.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
from garf_io import exceptions, formatter
3636
from garf_io.writers.abs_writer import AbsWriter
3737

38+
logger = logging.getLogger(__name__)
39+
3840

3941
class SheetWriterError(exceptions.GarfIoError):
4042
"""SheetWriterError specific errors."""
@@ -94,7 +96,7 @@ def write(
9496
sheet.append_rows(report.results, value_input_option='RAW')
9597

9698
success_msg = f'Report is saved to {sheet.url}'
97-
logging.info(success_msg)
99+
logger.info(success_msg)
98100
if self.share_with:
99101
self.spreadsheet.share(self.share_with, perm_type='user', role='writer')
100102
return success_msg

libs/io/garf_io/writers/sqldb_writer.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
from garf_io import formatter
3232
from garf_io.writers import abs_writer
3333

34+
logger = logging.getLogger(__name__)
35+
3436

3537
class SqlAlchemyWriter(abs_writer.AbsWriter):
3638
"""Handles writing GarfReports data to databases supported by SqlAlchemy.
@@ -77,7 +79,7 @@ def write(self, report: garf_report.GarfReport, destination: str) -> None:
7779
).head(0)
7880
else:
7981
df = report.to_pandas()
80-
logging.debug('Writing %d rows of data to %s', len(df), destination)
82+
logger.debug('Writing %d rows of data to %s', len(df), destination)
8183
write_params = {
8284
'name': destination,
8385
'con': self.engine,
@@ -87,7 +89,7 @@ def write(self, report: garf_report.GarfReport, destination: str) -> None:
8789
if dtypes:
8890
write_params.update({'dtype': dtypes})
8991
df.to_sql(**write_params)
90-
logging.debug('Writing to %s is completed', destination)
92+
logger.debug('Writing to %s is completed', destination)
9193

9294
@property
9395
def engine(self) -> sqlalchemy.engine.Engine:

0 commit comments

Comments
 (0)