惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
The Last Watchdog
The Last Watchdog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
G
Google Developers Blog
博客园 - 叶小钗
雷峰网
雷峰网
人人都是产品经理
人人都是产品经理
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 三生石上(FineUI控件)
Help Net Security
Help Net Security
Cloudbric
Cloudbric
AI
AI
N
News | PayPal Newsroom
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
Forbes - Security
Forbes - Security
美团技术团队
Stack Overflow Blog
Stack Overflow Blog
SecWiki News
SecWiki News
H
Heimdal Security Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MyScale Blog
MyScale Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
S
Security @ Cisco Blogs
Google DeepMind News
Google DeepMind News
V
V2EX
大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
S
Security Affairs
L
LangChain Blog
The Hacker News
The Hacker News
F
Full Disclosure
aimingoo的专栏
aimingoo的专栏
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
Webroot Blog
Webroot Blog
A
About on SuperTechFans
H
Hacker News: Front Page
Cyberwarzone
Cyberwarzone
WordPress大学
WordPress大学
L
LINUX DO - 热门话题
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Attack and Defense Labs
Attack and Defense Labs
M
MIT News - Artificial intelligence

Ivan on Containers, Kubernetes, and Server-Side

A grounded take on agentic coding for production environments Server-Side Playgrounds Reimagined: Build, Boot, and Network Your Own Virtual Labs [not a] Kubernetes 101 - Pods, Deployments, and Services As an Attempt To Automate Age-Old Infra Patterns JavaScript or TypeScript? How To Benefit From the Dichotomy On Software Design... and Good Writing Building a Firecracker-Powered Course Platform To Learn Docker and Kubernetes How To Publish a Port of a Running Container What Actually Happens When You Publish a Container Port A Visual Guide to SSH Tunnels: Local and Remote Port Forwarding Debugging Containers Like a Pro Docker: How To Debug Distroless And Slim Containers How To Extract Container Image Filesystem Using Docker | iximiuz Labs In Pursuit of Better Container Images: Alpine, Distroless, Apko, Chisel, DockerSlim, oh my! How To Start Programming In Go: Advice For Fellow DevOps Engineers Kubernetes Ephemeral Containers and kubectl debug Command How To Develop Kubernetes CLIs Like a Pro Docker Container Commands Explained: Understand, Don't Memorize | iximiuz Labs Learning Docker with Docker - Toying With DinD For Fun And Profit How To Extend Kubernetes API - Kubernetes vs. Django The Influence of Plumbing on Programming How To Call Kubernetes API from Go - Types and Common Machinery How To Call Kubernetes API using Simple HTTP Client Kubernetes API Basics - Resources, Kinds, and Objects OpenFaaS - Run Containerized Functions On Your Own Terms Learning Containers From The Bottom Up Docker Containers vs. Kubernetes Pods - Taking a Deeper Look | iximiuz Labs Learn-by-Doing Platforms for Dev, DevOps, and SRE Folks How HTTP Keep-Alive can cause TCP race condition How to Work with Container Images Using ctr | iximiuz Labs Multiple Containers, Same Port, no Reverse Proxy... Exploring Go net/http Package - On How Not To Set Socket Options Disposable Local Development Environments with Vagrant, Docker, and Arkade DevOps, SRE, and Platform Engineering My Choice of Programming Languages Prometheus Is Not a TSDB How to learn PromQL with Prometheus Playground Prometheus Cheat Sheet - Basics (Metrics, Labels, Time Series, Scraping) Rust - Writing Parsers With nom Parser Combinator Framework Prometheus Cheat Sheet - Moving Average, Max, Min, etc (Aggregation Over Time) Prometheus Cheat Sheet - How to Join Multiple Metrics (Vector Matching) The Need For Slimmer Containers Understanding Rust Privacy and Visibility Model Bridge vs. Switch: Takeaways from a Real Data Center Tour | iximiuz Labs From LAN to VXLAN: Networking Basics for Non-Network Engineers | iximiuz Labs KiND - How I Wasted a Day Loading Local Docker Images Go, HTTP handlers, panic, and deadlocks Exploring Kubernetes Operator Pattern Making Sense Out Of Cloud Native Buzz Service Discovery in Kubernetes: Combining the Best of Two Worlds API Developers Never REST How Container Networking Works: Building a Bridge Network From Scratch | iximiuz Labs Traefik: canary deployments with weighted load balancing Service Proxy, Pod, Sidecar, oh my! You Need Containers To Build Images You Don't Need an Image To Run a Container Not Every Container Has an Operating System Inside Working with container images in Go Master Go While Learning Containers Implementing Container Runtime Shim: Interactive Containers How to use Flask with gevent (uWSGI and Gunicorn editions) My 10 Years of Programming Experience Implementing Container Runtime Shim: First Code Implementing Container Runtime Shim: runc Kubernetes Repository On Flame Dealing with process termination in Linux (with Rust examples) conman - [the] Container Manager: Inception Journey From Containerization To Orchestration And Beyond Linux PTY - How docker attach and docker exec Commands Work Inside Illustrated introduction to Linux iptables From Docker Container to Bootable Linux Disk Image Пишем свой веб-сервер на Python: протокол HTTP 9001 способ создать веб-сервер на Python Explaining async/await in 200 lines of code Explaining event loop in 100 lines of code Save the day with gevent Пишем свой веб-сервер на Python: процессы, потоки и асинхронный I/O Truly optional scalar types in protobuf3 (with Go examples) Node.js Writable streams distilled Node.js Readable streams distilled How to on starting processes (mostly in Linux) Дайджест интересных ссылок – Июль 2016 Пишем свой веб-сервер на Python: сокеты Наследование в JavaScript Мастерить!
pq - parse and query log files as time series
Ivan Velichko · 2021-07-08 · via Ivan on Containers, Kubernetes, and Server-Side

I often find myself staring at Nginx or Envoy access logs flooding my screens with real-time data. My only wish at such moments is to be able to aggregate these lines somehow and analyze the output at a slower pace, ideally, with some familiar and concise query language. And to my surprise, I haven't met a tool satisfying all my requirements yet. Well, I should be honest here - I haven't done thorough research. But if there would be a tool as widely known as jq for JSON, I wouldn't miss it probably.

So, here we go - my attempt to write a full-fledged parsing and query engine and master Rust at the same time. Yes, I know, it's a bad idea. But who has time for good ones?

First things first - a usage preview:

Level up your server-side game — join 20,000 engineers getting insightful learning materials straight to their inbox.

The project is heavily influenced by jq and PromQL. Recently, I also learned about angle-grinder so I had a chance to incorporate some ideas from that wonderful but less known tool too.

I somehow tend to see logs as time-series data. So, I want to work with logs as with time series. In an ideal world, all the logs would be aggregated, parsed into fields and metrics, stored in ElasticSearch and Prometheus, and queried from Kibana and Grafana. However, we don't live in such a world just yet. So, I want to be able to quickly parse semi-structured files locally. The parsing result should be a stream of timestamped and strongly typed records. Having such a stream, I'd be able to query it with PromQL-like language. While angle-grinder is quite powerful at parsing and manipulating data, I still find it hardly usable to work with time series. On the contrary, I tried to design pq time-series-first. It has rather basic parsing capabilities, almost no transformation features, but extensive query functionality is a must.

Here is how a typical pq command may look like:

pq '/[^\[]+\[([^]]+)]\s+"([^\s]+)[^"]*?"\s+(\d+)\s+(\d+).*/
| map { .0:ts, .1 as method, .2:str as status_code, .3 as content_len } 
| sum(sum_over_time(content_len[1s])) by (method) / 1024'

A program consists of a mandatory decoding step, followed by an optional mapping step, and by another optional query step separated by the | symbol. Below I'll put some screencasted demos, and don't forget to check out the README file for a more technical explanation.

Decoding:

Mapping:

Querying and formatting:

To eat my own dog food, I used pq to analyze the Nginx access.log file of this blog. I hacked a tiny HTML page to visualize the JSON produced by pq:

Monthly page views by post language:

pq '
/([^\s]+).*?\[([^\]]+).*?"([A-Z]+)\s+\/(en|ru)\/posts\/([a-z0-9-]+)\/.*?HTTP.*?(\d+)\s+(\d+)/
| map {
    .0 as ip,
    .1:ts,
    .2 as method,
    .3 as lang,
    .4 as post,
    .5:str as status_code,
    .6 as content_len
  }
| select sum(
      count_over_time(
          __line__{method="GET", status_code="200"}[4w]
      )
  ) by (lang)
| to_json'

Monthly pageviews by blog post language.

Monthly page views by post:

pq '
/([^\s]+).*?\[([^\]]+).*?"([A-Z]+)\s+\/(en|ru)\/posts\/([a-z0-9-]+)\/.*?HTTP.*?(\d+)\s+(\d+)/
| map {
    .0 as ip,
    .1:ts,
    .2 as method,
    .3 as lang,
    .4 as post,
    .5:str as status_code,
    .6 as content_len
  }
| select sum(
      count_over_time(
          __line__{method="GET", status_code="200"}[4w]
      )
  ) by (post)
| to_json  

Monthly pageviews by blog post.

The above graph looks a bit overwhelming, so here is Top 10 posts by monthly page views:

pq '
/([^\s]+).*?\[([^\]]+).*?"([A-Z]+)\s+\/(en|ru)\/posts\/([a-z0-9-]+)\/.*?HTTP.*?(\d+)\s+(\d+)/
| map {
    .0 as ip,
    .1:ts,
    .2 as method,
    .3 as lang,
    .4 as post,
    .5:str as status_code,
    .6 as content_len
  }
| select topk(
      10,
      sum(
          count_over_time(
              __line__{method="GET", status_code="200"}[4w]
          )
      ) by (post)
  )
| to_json'

Monthly Top-10 blog post.

While working on pq, I often needed to dig into Prometheus code for better understanding of some query logic. So, if you deal with PromQL, I tried to share some of my findings on the way:

Fun fact

I've been starting to write this tool several times already. The first attempt was somewhere in 2014, but I didn't manage to produce anything meaningful then. In 2016, I started the echelon0 project, and it happily coincided with a wonderful time of becoming a father of a little girl. Obviously, I didn't get any spare time for this side project. In 2019 I finally got a chance to work on it again, this time under the codename amnis. However, I overcomplicated it right from the beginning. The design was so powerful and all-around that I never got to the code. And finally, pq resulted in something more or less functional.

Cheers!

Level up your server-side game — join 20,000 engineers getting insightful learning materials straight to their inbox: