{"id":1124,"date":"2026-01-09T22:45:20","date_gmt":"2026-01-10T06:45:20","guid":{"rendered":"https:\/\/www.gauntletwizard.net\/wordpress\/?p=1124"},"modified":"2026-01-09T22:46:03","modified_gmt":"2026-01-10T06:46:03","slug":"sqlite-over-alblogs","status":"publish","type":"post","link":"https:\/\/www.gauntletwizard.net\/wordpress\/?p=1124","title":{"rendered":"Sqlite over ALBLogs"},"content":{"rendered":"\n<p>This is a short on my journey to do some simple log processing. My client had a backend issue with a particular request path, and I was able to identify the source of errors and the source of slowness pretty easily with this.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 id=\"identify-s3-bucket-and-copy-locally\">Identify S3 bucket and copy locally<\/h2>\n\n\n\n<p>First, you&#8217;ve got to identify where your S3 logs are. This is really easy from the console; Click the load balancer, check the attributes section, and see where it is. <\/p>\n\n\n\n<p>Alternatively, from the cli:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># List load balancers\naws elbv2 describe-load-balancers\naws elbv2 describe-load-balancers  | jq -r '.LoadBalancers&#91;] | (.LoadBalancerName + \" \" + .LoadBalancerArn)'\n# Look for access_logs.s3.bucket and access_logs.s3.prefix\naws elbv2 describe-load-balancer-attributes --load-balancer-arn ARN\naws elbv2 describe-load-balancer-attributes --load-balancer-arn ARN | jq '.Attributes&#91;] | select( (.Key == \"access_logs.s3.bucket\" or .Key == \"access_logs.s3.prefix\"))'\n<\/code><\/pre>\n\n\n\n<p>Once you&#8217;ve got the location, you can copy it down with<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>aws s3 sync s3:\/\/lb-logs\/prefix\/date\/ scratch\/alblogs<\/code><\/pre>\n\n\n\n<h2 id=\"unpack-and-concat\">Unpack and Concat<\/h2>\n\n\n\n<p>Now you&#8217;ve got a big directory full of small logfiles. Unpack them and put them all in one big file for sqlite import:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>zcat * > all.log<\/code><\/pre>\n\n\n\n<h2 id=\"create-sql\">Create SQL<\/h2>\n\n\n\n<p>First, create the schema for your ALBLogs. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE TABLE IF NOT EXISTS \"alblogs\"(\n \"type\" TEXT, \"time\" TEXT, \"elb\" TEXT, \"client_port\" TEXT,\n \"target_port\" TEXT, \"request_processing_time\" int, \"target_processing_time\" int, \"response_processing_time\" int,\n \"elb_status_code\" TEXT, \"target_status_code\" TEXT, \"received_bytes\" int, \"sent_bytes\" int,\n \"request\" TEXT, \"user_agent\" TEXT, \"ssl_cipher\" TEXT, \"ssl_protocol\" TEXT,\n \"target_group_arn\" TEXT, \"trace_id\" TEXT, \"domain_name\" TEXT, \"chosen_cert_arn\" TEXT,\n \"matched_rule_priority\" TEXT, \"request_creation_time\" TEXT, \"actions_executed\" TEXT, \"redirect_url\" TEXT,\n \"error_reason\" TEXT, \"target_port_list\" TEXT, \"target_status_code_list\" TEXT, \"classification\" TEXT,\n \"classification_reason\" TEXT, \"conn_trace_id\" TEXT,\n \"transformed_host\" TEXT, \"transformed_uri\" TEXT, \"request_transform_status\" TEXT\n);\n<\/code><\/pre>\n\n\n\n<p>Then, import your logfile into a table:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.separator \" \"\n.import \"all.log\" alblogs<\/code><\/pre>\n\n\n\n<p>For really useful work, you&#8217;ll likely need a regex implementation. Depending on your distro, you might already have one installed. I specifically installed sqlite3-pcre. You activate one like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.load \/usr\/lib\/libsqlite3-pcre.so<\/code><\/pre>\n\n\n\n<p>That&#8217;s it! You&#8217;re now ready to query your logs.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>select request, target_processing_time from alblogs order by target_processing_time desc limit 10;<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a short on my journey to do some simple log processing. My client had a backend issue with a particular request path, and I was able to identify the source of errors and the source of slowness pretty easily with this. Identify S3 bucket and copy locally First, you&#8217;ve got to identify where &hellip; <a href=\"https:\/\/www.gauntletwizard.net\/wordpress\/?p=1124\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Sqlite over ALBLogs<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1124"}],"collection":[{"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1124"}],"version-history":[{"count":5,"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1124\/revisions"}],"predecessor-version":[{"id":1130,"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1124\/revisions\/1130"}],"wp:attachment":[{"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gauntletwizard.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}