What is PromQL?

PromQL (Prometheus Query Language) is the query language for retrieving and aggregating data in Prometheus.

Data types

Prometheus supports four data types (see Expression language data types):

Instant vectorA set of time series at a single timestamp
Range vectorA set of time series over a time range
ScalarA single numeric value
StringA string value

Label matchers

Prometheus stores time series with labels. By specifying labels you can select specific series.

For example, to select only those with job="prometheus" for metric http_requests_total:

http_requests_total{job="prometheus"}

Available operators:

=equals
!=not equals
=~regex match
!~regex not match

Metric types

Prometheus metrics come in four types:

GaugeGauge
CounterCounter
HistogramHistogram
SummarySummary

For differences between Histogram and Summary, see HISTOGRAMS AND SUMMARIES. For latency calculation details, see this post (Japanese).

Aggregation

Use aggregation operators to aggregate vectors, e.g.:

  • sum
  • min
  • max
  • avg

Example: total HTTP requests

sum(http_requests_total)

Reference: Aggregation operators

Functions

PromQL provides many functions over time series. Functions accept either an instant vector or a range vector; the docs specify the type.

Examples:

  • absent(v instant-vector) checks for the absence of elements.
  • absent_over_time(v range-vector) checks absence over a range.
  • exp(v instant-vector) computes the exponential.

See the official docs for more: functions.

rate / irate

rate and irate compute the per‑second increase of counter metrics.

rate(v range-vector) Average increase rate for slowly changing counters.

irate(v range-vector) Instantaneous rate for fast‑changing counters. Use this when spikes make rate hard to observe.

Counter reset Counters may reset on restart. When using rate or irate, resets are handled automatically. When aggregating, build on rate~/~irate to avoid reset artifacts. Example with sum:

sum(rate(http_request_total[5m]))

overtime aggregation functions

Functions of the form <aggregation>_over_time(range-vector) aggregate over time and return an instant vector.

avg_over_time(range-vector)Average over the range
min_over_time(range-vector)Minimum over the range
max_over_time(range-vector)Maximum over the range
sum_over_time(range-vector)Sum over the range

References

Official Prometheus docs

What is Alertmanager?

Alertmanager sends alerts (e.g., email/Slack) when Prometheus metrics satisfy configured conditions.

Installation

You can spin up Prometheus with Docker Compose using this repo: → Install docker-compose

Start with:

$ git clone https://github.com/vegasbrianc/prometheus
$ cd prometheus
$ docker-compose up

Ports:

Prometheushttp://localhost:9090/
Alertmanagerhttp://localhost:9093/

Slack notifications

Create a Slack app for Prometheus, enable Incoming Webhooks, and get the webhook URL.

Set username, channel, and api_url in alertmanager/config.yml:

route:
 receiver: 'slack'

receivers:
 - name: 'slack'
   slack_configs:
       - send_resolved: true
         username: '<username>'
         channel: '<channel name>'
         api_url: '<webhook url>'

Alertmanager configuration

Define alert rules like this:

groups:
- name: <rule name>
  rules:
  - alert: <alert name>
    expr: <PromQL expression>
    for: <duration>
    severity: <severity>
    annotations:
      description: "Alert description"
      summary: "Summary"
alertAlert name
exprPromQL expression
forHow long the condition must hold (s, m, h, d)
severitySeverity (e.g., critical, warning)
annotationsDescription and summary

In this repo, rules live in prometheus/alert.rules.

To force an example alert, set expr to 1 as below:

groups:
- name: rule-example
  rules:
  - alert: alert-example
    expr: 1
    for: 1m

After editing, restart the Docker containers to apply changes. After a short wait, http://localhost:9090/alerts shows the alert as active.

Image

Status is PENDING or FIRING; FIRING means the alert is firing.

Alertmanager shows fired alerts:

Image

Slack also receives the notification:

Image

References

Goal

Old issues often remain open. We want to close stale issues automatically.

Stale

Using Stale you can automatically mark and close inactive issues/PRs.

The GitHub Actions bot will mark items as stale like this (this example is configured to stale and close quickly for testing):

Image

Installation steps

From the Actions tab of your repository, create a workflow from a template.

Image

Scroll down to “Automate every step in your process” and select Stale.

Image

Click “Set up this workflow” to open the editor.

Image

By default issues go stale after 60 days and close 7 days later.

You can customize options. For example, to stale after 30 days and close after 5 days, write the following in .github/workflows/stale.yml:

name: Mark stale issues and pull requests

on:
  schedule:
  - cron: "30 1 * * *"

jobs:
  stale:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/stale@v3
      with:
        repo-token: ${{ secrets.GITHUB_TOKEN }}
        stale-issue-message: 'Stale issue message'
        stale-pr-message: 'Stale pull request message'
        stale-issue-label: 'no-issue-activity'
        stale-pr-label: 'no-pr-activity'
        days-before-stale: 30
        days-before-close: 5

See the README for additional settings.

Introduction

When you need to run code periodically, Cloud Functions for Firebase can help. It’s handy for tasks that must run at fixed times.

Use cases

  • Aggregate Firestore user data once per day
  • Delete obsolete data

How it works

Internally, the cron service Cloud Scheduler publishes a message to a Pub/Sub topic. A Cloud Function subscribes to that topic to schedule execution.

Installation

Switch to the Blaze plan

This isn’t available on the free plan; switch to the pay‑as‑you‑go Blaze plan.

Install tools

$ npm install -g firebase-tools

Log in:

$ firebase login

Initialize:

$ firebase init functions

Writing functions

To set a region, use functions.region. Example that runs every minute:

Intervals are specified using either the cron schedule format or the App Engine cron format.

exports.scheduledFunction = functions.region('asia-northeast1')
  .pubsub.schedule('every 1 minutes')
  .timeZone('Asia/Tokyo')
  .onRun(() => {
    console.info('hello world');
  });

Deploy:

$ firebase deploy --only functions

After deployment, the scheduled job appears under Functions as shown below.

Image

References

Official Firebase docs (Japanese)

What is Percona XtraDB Cluster?

Percona’s open‑source database clustering system. It uses Galera Cluster to cluster MySQL, resulting in a master/master (multi‑master) configuration where every node can both read and write.

Beware of DDL (table changes)

Because PXC is multi‑master, you need to take care when executing DDL. There are two modes for DDL: TOI (Total Order Isolation) and RSU (Rolling Schema Upgrade).

With TOI, the DDL runs on all nodes at the same time, but transactions wait until the DDL finishes. If a table is large, avoid running ALTER TABLE while the service is live.

With RSU, the node executing the DDL temporarily leaves the cluster, runs the DDL, then rejoins and applies the delta. By updating one node at a time you can avoid downtime, but operations such as dropping or changing columns that already took effect elsewhere cannot be performed.

If you need to make disruptive changes without downtime, you can use pt-online-schema-change, though it increases server load.

References

What I Bought

FLEXISPOT EN1B

  • List price: 33,100 JPY
  • 10% off at the time, paid about 30,000 JPY

https://amzn.asia/d/eNWTOYv

Electric screwdriver

  • Needed to attach the desktop to the FlexiSpot frame.
  • Didn’t want an oversized drill I’d rarely use, so I bought this.
  • 2,980 JPY

https://amzn.asia/d/3yu75sk

Desktop: Acacia

  • Bought at a home improvement store
  • Size: 65 cm (D) × 140 cm (W) after cutting
  • About 10,000 JPY total
  • Cutting: 160 JPY
  • Shipping: 2,000 JPY
  • Wood: 7,000 JPY

Sandpaper

  • Needed for sanding the wood
  • Mainly used grit 600
  • 980 JPY

https://amzn.asia/d/cjK8AGH

Watco wax

Also bought a small tin container and a brush for applying the oil.

Assembly

Sanding

  • Sand the entire surface before applying oil.
  • Sand the top and edges until they feel smooth to the touch.

Oil finish

  • After sanding, apply Watco oil.
  • After covering the whole surface, wait about 15 minutes, wipe off excess oil, then let it dry for about an hour.
  • Once dry, repeat the same process one more time.
  • Finish by lightly sanding with sandpaper and wiping off any remaining oil.
Applying oil

Applying oil

Drying

Drying

After oil finish

After oil finish

Putting it together

  • Use the electric screwdriver when mounting the desktop.
  • It’s tough alone; if possible, assemble with two people.

Finished

Seated height

Standing height

Showing 21 - 26 of 26