@@ -241,6 +241,115 @@ Resources:
241241 field.delim : " \t "
242242 serialization.format : " \t "
243243
244+ # --- Athena Named Queries ---
245+
246+ PopularPagesQuery :
247+ Type : AWS::Athena::NamedQuery
248+ Properties :
249+ Name : !Sub "${AWS::StackName}-popular-pages"
250+ Description : Top 25 pages by request count
251+ WorkGroup : !Ref AthenaWorkGroup
252+ Database : !Ref AthenaDatabase
253+ QueryString : !Sub |
254+ SELECT uri_stem, COUNT(*) as requests
255+ FROM ${AthenaDatabaseName}.cloudfront_access_logs
256+ GROUP BY uri_stem
257+ ORDER BY requests DESC
258+ LIMIT 25
259+
260+ ErrorAnalysisQuery :
261+ Type : AWS::Athena::NamedQuery
262+ Properties :
263+ Name : !Sub "${AWS::StackName}-error-analysis"
264+ Description : Requests grouped by status code
265+ WorkGroup : !Ref AthenaWorkGroup
266+ Database : !Ref AthenaDatabase
267+ QueryString : !Sub |
268+ SELECT status_code, COUNT(*) as requests
269+ FROM ${AthenaDatabaseName}.cloudfront_access_logs
270+ GROUP BY status_code
271+ ORDER BY requests DESC
272+
273+ NotFoundQuery :
274+ Type : AWS::Athena::NamedQuery
275+ Properties :
276+ Name : !Sub "${AWS::StackName}-not-found"
277+ Description : Top 404 paths
278+ WorkGroup : !Ref AthenaWorkGroup
279+ Database : !Ref AthenaDatabase
280+ QueryString : !Sub |
281+ SELECT uri_stem, COUNT(*) as count
282+ FROM ${AthenaDatabaseName}.cloudfront_access_logs
283+ WHERE status_code = 404
284+ GROUP BY uri_stem
285+ ORDER BY count DESC
286+ LIMIT 25
287+
288+ AiCrawlerQuery :
289+ Type : AWS::Athena::NamedQuery
290+ Properties :
291+ Name : !Sub "${AWS::StackName}-ai-crawlers"
292+ Description : AI bot traffic (GPTBot, ClaudeBot, ByteSpider, etc.)
293+ WorkGroup : !Ref AthenaWorkGroup
294+ Database : !Ref AthenaDatabase
295+ QueryString : !Sub |
296+ SELECT url_decode(user_agent) as user_agent,
297+ COUNT(*) as requests, COUNT(DISTINCT client_ip) as unique_ips
298+ FROM ${AthenaDatabaseName}.cloudfront_access_logs
299+ WHERE LOWER(url_decode(user_agent)) LIKE '%gptbot%'
300+ OR LOWER(url_decode(user_agent)) LIKE '%claudebot%'
301+ OR LOWER(url_decode(user_agent)) LIKE '%bytespider%'
302+ OR LOWER(url_decode(user_agent)) LIKE '%ccbot%'
303+ OR LOWER(url_decode(user_agent)) LIKE '%perplexitybot%'
304+ OR LOWER(url_decode(user_agent)) LIKE '%amazonbot%'
305+ OR LOWER(url_decode(user_agent)) LIKE '%google-extended%'
306+ GROUP BY user_agent
307+ ORDER BY requests DESC
308+
309+ TrafficPerDayQuery :
310+ Type : AWS::Athena::NamedQuery
311+ Properties :
312+ Name : !Sub "${AWS::StackName}-traffic-per-day"
313+ Description : Daily request counts
314+ WorkGroup : !Ref AthenaWorkGroup
315+ Database : !Ref AthenaDatabase
316+ QueryString : !Sub |
317+ SELECT log_date, COUNT(*) as requests
318+ FROM ${AthenaDatabaseName}.cloudfront_access_logs
319+ GROUP BY log_date
320+ ORDER BY log_date DESC
321+
322+ CacheHitRateQuery :
323+ Type : AWS::Athena::NamedQuery
324+ Properties :
325+ Name : !Sub "${AWS::StackName}-cache-hit-rate"
326+ Description : Cache hit percentage by day
327+ WorkGroup : !Ref AthenaWorkGroup
328+ Database : !Ref AthenaDatabase
329+ QueryString : !Sub |
330+ SELECT log_date,
331+ COUNT(*) as total,
332+ SUM(CASE WHEN edge_result_type = 'Hit' THEN 1 ELSE 0 END) as hits,
333+ ROUND(100.0 * SUM(CASE WHEN edge_result_type = 'Hit' THEN 1 ELSE 0 END) / COUNT(*), 1) as hit_pct
334+ FROM ${AthenaDatabaseName}.cloudfront_access_logs
335+ GROUP BY log_date
336+ ORDER BY log_date DESC
337+
338+ TopReferrersQuery :
339+ Type : AWS::Athena::NamedQuery
340+ Properties :
341+ Name : !Sub "${AWS::StackName}-top-referrers"
342+ Description : Top referrers (where traffic comes from)
343+ WorkGroup : !Ref AthenaWorkGroup
344+ Database : !Ref AthenaDatabase
345+ QueryString : !Sub |
346+ SELECT url_decode(referer) as referer, COUNT(*) as requests
347+ FROM ${AthenaDatabaseName}.cloudfront_access_logs
348+ WHERE referer != '-'
349+ GROUP BY referer
350+ ORDER BY requests DESC
351+ LIMIT 25
352+
244353Outputs :
245354 ContentBucketName :
246355 Value : !Ref ContentBucket
@@ -291,3 +400,24 @@ Outputs:
291400 AthenaDatabaseName :
292401 Description : Athena database name
293402 Value : !Ref AthenaDatabase
403+
404+ PopularPagesQueryId :
405+ Value : !Ref PopularPagesQuery
406+
407+ ErrorAnalysisQueryId :
408+ Value : !Ref ErrorAnalysisQuery
409+
410+ NotFoundQueryId :
411+ Value : !Ref NotFoundQuery
412+
413+ AiCrawlerQueryId :
414+ Value : !Ref AiCrawlerQuery
415+
416+ TrafficPerDayQueryId :
417+ Value : !Ref TrafficPerDayQuery
418+
419+ CacheHitRateQueryId :
420+ Value : !Ref CacheHitRateQuery
421+
422+ TopReferrersQueryId :
423+ Value : !Ref TopReferrersQuery
0 commit comments