在气流中,可以使用简单的print()
或建议的记录器here来记录日志
但是,当尝试在操作员内部进行打印时,这将不起作用。
我有以下代码:
for i in range(5, 0, -1):
gcs_export_uri_template = ["adstest/{{ macros.ds_format(macros.ds_add(ds, -params.i), '%Y-%m-%d', '%Y/%m/%d') }}/*"]
update_bigquery = GoogleCloudStorageToBigQueryOperator(
dag=dag,
task_id='load_ads_to_BigQuery-{}'.format(i),
bucket=GCS_BUCKET_ID,
destination_project_dataset_table=table_name_template,
source_format='CSV',
source_objects=gcs_export_uri_template,
schema_fields=dc(),
params={'i': i},
create_disposition='CREATE_IF_NEEDED',
write_disposition='WRITE_APPEND',
skip_leading_rows=1,
google_cloud_storage_conn_id=CONNECTION_ID,
bigquery_conn_id=CONNECTION_ID
)
现在说我想打印"My name is load_ads_to_BigQuery-{}".format{i)
如您所见,每个操作员的打印件都是统一的。
如果我这样做的话:
for i in range(5, 0, -1):
print("My name is load_ads_to_BigQuery-{}".format{i))
gcs_export_uri_template = ...
update_bigquery = GoogleCloudStorageToBigQueryOperator(...)
所有5个操作员将打印所有5张照片。在我看来,这是不正确的。
打印件必须在GoogleCloudStorageToBigQueryOperator
内。
我该怎么做?
答案 0 :(得分:1)
一个可能足够的解决方案是创建一个包装器类。示例:
class MyGoogleCloudStorageToBigQueryOperator(BaseOperator):
template_fields = ('bucket', 'source_objects',
'schema_object', 'destination_project_dataset_table')
@apply_defaults
def __init__(self,
bucket,
destination_project_dataset_table,
source_format,
source_objects,
schema_fields,
params,
create_disposition,
write_disposition,
skip_leading_rows,
google_cloud_storage_conn_id,
bigquery_conn_id,
*args,
**kwargs):
super(InfogroupFilestreamOperator, self).__init__(*args, **kwargs)
self.bucket= bucket
self.destination_project_dataset_table=destination_project_dataset_table
...
def execute(self, context):
self.log.info("My name is %s", self.task_id)
hook=GoogleCloudStorageToBigQueryOperator(
task_id="doesnt_matter",
bucket=self.bucket,
source_format=self.source_format,
...
)
return hook.execute(context)
然后可以实例化 MyGoogleCloudStorageToBigQueryOperator
而不是for循环中的GoogleCloudStorageToBigQueryOperator
。
答案 1 :(得分:1)
基于@judoole的答案,您可以直接扩展GoogleCloudStorageToBigQueryOperator
。
class MyGoogleCloudStorageToBigQueryOperator(LoggingMixin, GoogleCloudStorageToBigQueryOperator):
def execute(self, context):
self.logger.info('Inside task {task_id}'.format(task_id=context['task_id']))
super().execute(context)
通常,您可以编写一个mixin类,该类将自动为各种操作员执行这种类型的日志记录。
class LogTaskExecutionMixin(object):
def execute(self, context):
self.logger.info('Inside task {task_id}'.format(task_id=context['task_id']))
super().execute(context)
class MyGoogleCloudStorageToBigQueryOperator(
LogTaskExecutionMixin, LoggingMixin, GoogleCloudStorageToBigQueryOperator
):
pass
这两种方法的思想都是定义一个新的运算符,该运算符在执行之前会写一条日志消息,但在其他方面与您扩展的运算符相同。