Not sure whether this I should have tagged this google-cloud-logging or google-workflows as I'm not sure whether the problem lies, so I tagged both.
I have a Google Cloud Workflow (the workflow definition is provided below) that executes a BigQuery stored procedure via the BigQuery jobs.insert REST API. I would like to log a message that provides a URL to that results of that job in the Google Cloud Console.
Thanks to the answer received at Is it possible to link to a job in the bigquery console? I know I can construct a URL that takes me to the query result, it looks like this:
https://console.cloud.google.com/bigquery?project=<my-project>j=<bq:<location>:<job_id>>&page=queryresults
Hence I am logging a message from my Google Cloud Workflow to Google Cloud Logging containing that URL. Here is the portion of my workflow that does it:
- bq_job_get_post_completion:
call: bqJobGet
args:
project_id: ${project_id}
job_id: ${job_id}
result: bq_job_get_response
- set_job_completion_vars:
assign:
- jobCompletionStats:
jobId: ${job_id}
totalBytesBilled: ${bq_job_get_response.body.statistics.query.totalBytesBilled}
totalBytesProcessed: ${bq_job_get_response.body.statistics.query.totalBytesProcessed}
totalSlotMs: ${bq_job_get_response.body.statistics.query.totalSlotMs}
jobDetailsUrl: ${"https://console.cloud.google.com/bigquery?project=" + project_id + "&j=bq:EU:" + job_id + "&page=queryresults"}
Note the jobDetailsUrl part.
Unfortunately when this gets appears in cloud logging the URL looks like this:
https://console.cloud.google.com/bigquery?project=my-redacted-project\u0026j=bq:EU:job_XXXXXX\u0026page=queryresults
As you might be able to see, the ampersands have been replaced with \u0026. I understand why this is, 26 is the unicode character code for an ampersand...however the URL no-longer takes me direct to the correct result in the Google Cloud Console - essentially the pertinent information in the URL has been invalidated.
Can anyone advise how I can stop this from happening? I want the correct URL to appear in the cloud logging.
Here is the entirety of my workflow:
main:
steps:
- call_subWorkflow:
call: callBQStoredProc
args:
stored_proc_name: "mydataset.my-stored-procedure"
project_id: my-redacted-project
#SUBWORKFLOWS
callBQStoredProc:
params: [stored_proc_name, project_id, poll_wait_time_seconds: 5]
steps:
- init:
assign:
- job:
jobReference:
location: EU
configuration:
query:
useLegacySql: false
useQueryCache: false
query: ${"call " + stored_proc_name + "()"}
- log_start:
call: sys.log
args:
text: >
${"Starting execution of bigquery stored procedure \"" + stored_proc_name + "\" using subworkflow executeBQStoredProc"}
severity: INFO
- postCallStoredProc:
call: http.post
args:
url: ${"https://bigquery.googleapis.com/bigquery/v2/projects/" + project_id + "/jobs"}
body: ${job}
auth:
type: OAuth2
result: bq_jobs_insert_response
- set_job_id:
assign:
- job_id: ${bq_jobs_insert_response.body.jobReference.jobId}
- bq_job_get:
call: bqJobGet
args:
project_id: ${project_id}
job_id: ${job_id}
result: bq_job_get_response
- set_job_vars:
assign:
- job_state: ${bq_job_get_response.body.status.state}
- job_project: ${bq_job_get_response.body.jobReference.projectId}
- log_job_state:
call: sys.log
args:
text: >
${"Job " + job_id + " in project " + job_project + " has state : " + job_state}
severity: INFO
- check_job_state:
switch:
- condition: ${job_state != "DONE"}
steps:
- wait_10s:
call: sys.sleep
args:
seconds: ${int(poll_wait_time_seconds)}
next: bq_job_get
- bq_job_get_post_completion:
call: bqJobGet
args:
project_id: ${project_id}
job_id: ${job_id}
result: bq_job_get_response
- set_job_completion_vars:
assign:
- jobCompletionStats:
jobId: ${job_id}
totalBytesBilled: ${bq_job_get_response.body.statistics.query.totalBytesBilled}
totalBytesProcessed: ${bq_job_get_response.body.statistics.query.totalBytesProcessed}
totalSlotMs: ${bq_job_get_response.body.statistics.query.totalSlotMs}
jobDetailsUrl: ${"https://console.cloud.google.com/bigquery?project=" + project_id + "&j=bq:EU:" + job_id + "&page=queryresults"}
- log_job_completion:
call: sys.log
args:
text: ${jobCompletionStats}
severity: INFO
- bq_job_get_query_results:
call: http.request
args:
url: ${"https://bigquery.googleapis.com/bigquery/v2/projects/" + project_id + "/queries/" + job_id}
method: GET
auth:
type: OAuth2
result: bq_job_get_query_results_response
- returnResult:
return: ${bq_job_get_query_results_response.body}
bqJobGet:
params: [project_id, job_id]
steps:
- bq_job_get:
call: http.request
args:
url: ${"https://bigquery.googleapis.com/bigquery/v2/projects/" + project_id + "/jobs/" + job_id}
method: GET
auth:
type: OAuth2
result: bq_job_get_response
- returnResult:
return: ${bq_job_get_response}
You are trying to log a map as text. In the documentation of the sys.log function there is also the option to log a json. You simply need to replace 'text' with 'json' like this:
Another option would be to log the url in an own logging step like this:
Hope that gives you the desired output.