I'd like to generate a URL for AWS Cloud Watch Logs Insights page where I can customize the following parameters:
I couldn't find any official documentation for the structure of the URL. Also no API (at least not in boto3) would help me in this.
Here is an example:
https://eu-west-1.console.aws.amazon.com/cloudwatch/home?region=eu-west-1#logsV2:logs-insights$3FqueryDetail$3D$257E$2528end$257E$25272021-07-18T20*3a59*3a59.000Z$257Estart$257E$25272021-07-15T21*3a00*3a00.000Z$257EtimeType$257E$2527ABSOLUTE$257Etz$257E$2527Local$257EeditorString$257E$2527fields*20*40timestamp*2c*20*40message*0a*7c*20sort*20*40timestamp*20desc*0a*7c*20filter*20*40message*20*3d*7e*20*22Exception*22*0a*7c*20limit*20200$257EisLiveTail$257Efalse$257EqueryId$257E$2527####$257Esource$257E$2528$257E$2527*2faws*2flambda*2f######$2529$2529$26tab$3Dlogs
What is the encoding used to generate the URL above?
I'm thinking about simply replace the strings above with the desired params, any better way to achieve this ?
A clean implementation in TypeScript available here written by Danylo Fedorov, Thanks!
Replacing the strings in the URL isn't that direct, I did the following in Python that will generate link for the logs insights page:
def generate_cloudwatch_url(log_groups, query):
def escape(s):
for c in s:
if c.isalpha() or c.isdigit() or c in ["-", "."]:
continue
c_hex = "*{0:02x}".format(ord(c))
s = s.replace(c, c_hex)
return s
def gen_log_insights_url(params):
S1 = "$257E"
S2 = "$2528"
S3 = "$2527"
S4 = "$2529"
res = f"{S1}{S2}"
for k in params:
value = params[k]
if isinstance(value, str):
value = escape(value)
elif isinstance(value, list):
for i in range(len(value)):
value[i] = escape(value[i])
prefix = S1 if list(params.items())[0][0] != k else ""
suffix = f"{S1}{S3}"
if isinstance(value, list):
value = "".join([f"{S1}{S3}{n}" for n in value])
suffix = f"{S1}{S2}"
elif isinstance(value, int) or isinstance(value, bool):
value = str(value).lower()
suffix = S1
res += f"{prefix}{k}{suffix}{value}"
res += f"{S4}{S4}"
QUERY = f"logsV2:logs-insights$3Ftab$3Dlogs$26queryDetail$3D{res}"
return f"https://eu-west-1.console.aws.amazon.com/cloudwatch/home?region=eu-west-1#{QUERY}"
query_vars = {"sample":"value"}
query = "\n".join([f'| filter {k}="{v}"' for (k, v) in query_vars.items()])
params = {
"end": 0, # "2021-07-18T20:00:00.000Z",
"start": -60 * 60 * 24, # "2021-07-15T21:00:00.000Z",
"unit": "seconds",
"timeType": "RELATIVE", # "ABSOLUTE", # OR RELATIVE and end = 0 and start is negative seconds
"tz": "Local", # OR "UTC"
"editorString": f"fields @timestamp, @message\n| sort @timestamp desc\n{query}\n| limit 200",
"isLiveTail": False,
"source": [f"/aws/lambda/{lg}" for lg in log_groups],
}
return gen_log_insights_url(params)
I know it's aweful implementation, but it works!