serial-logger logs the times at which a specific serial of a DNS zone becomes active on various name servers within a DNS infrastructure. To achieve this, all name server are configured to send NOTIFYs to the serial-logger. This enables accurate measurement of DNS propagation delay and helps assess compliance with SLA (Service Level Agreement) targets.
The logger tracks zone propagation across multiple stages: from the customer's hidden primary name server, through the incoming and distribution layers, up to the public (anycast) name servers.
✅ This script is actively used by RcodeZero DNS, a professional DNS service provider, to monitor DNS zone propagation across its global infrastructure.
Name servers can be configured to send NOTIFYs to other name servers to inform them about a new version of a zone. The sending of the NOTIFYs is usually done immediately after loading the new zone version.
The zone propagation delay is defined as the time difference between when a new zone becomes active on a primary name server and when the same zone version becomes active on a secondary name server. When sending of notifications are enabled, the time difference of receiving NOTIFYs from the primary name server and the secondary name server is a good indicator of the zone propagation delay.
The architecture supports four name server roles:
- Customer: The hidden primary name server of the customer. It sends NOTIFY messages and serves as the primary name server for zone transfers.
- Incoming: Internal name servers in the DNS infrastructure that receive zone transfers directly from the customer’s hidden primary.
- Distribution: Internal servers responsible for distributing zones to the public-facing (anycast) name servers.
- Secondary: Public anycast name servers that serve the zones to the world.
The software includes a daemon that listens for and processes incoming NOTIFY messages, logging the time each serial is observed.
The DNS server code is inspired by this Gist: https://gist.github.com/pklaus/b5a7876d4d2cf7271873
The idea of sending NOTIFYs from all the name servers to a central collector was coming from Jake Zack's presentation "Embracing SLA's: How Customer Requirements Drive Innovation" held at "OARC 39 & 47th CENTR Technical Workshop": https://indico.dns-oarc.net/event/44/contributions/960/attachments/915/1715/JakeZack-OARCCENTR-Embracing-SLAs.pdf (slide 10)
Customer Incoming Distribution Secondary
+---+ +---+ +---+ +---+
| C | -------> | I | -------> | D | -----------> | S |
+---+ +---+ +---+ +---+
| Δ1 | |
| <----------- | |
| | Δ2 | |
| | <----------- | |
| | Δ3 |
| | <--------------- |
- Δ1: Delay from Customer to Incoming
- Δ2: Delay from Incoming to Distribution
- Δ3: Delay from Distribution to Secondary
- Customer-Lag: From the customer to the public facing name server: Δ1 + Δ2 + Δ3
- Incoming-Lag: From the time the zone was received by the DNS provider to the public facing name server: Δ2 + Δ3. This is the 'delay' inside the DNS provider
- Distribution-Lag: Δ3. Between the incoming and distribution name server, the DNS provider may perform certain checks on the zone which take time. After that checks, the zone will be distributed.
This project uses a PostgreSQL schema named tlddns to manage and analyze DNS NOTIFY traffic and SLA compliance. Below is a breakdown of the schema and its components:
Stores information about received DNS NOTIFY messages and the propagation delays to various name server types.
srcip: Source IP address of the NOTIFYzone: Zone name (e.g. 'at')received_at: Timestamp when the NOTIFY was received at the serial-logger (generated by the serial-logger)serial: Zone serial numberns_type: ENUM indicating the type of name server (customer, incoming, distribution, secondary)distribution_lag,incoming_lag,customer_lag: Propagation delay indicators
Purpose: Track how long it takes a zone update to propagate to various types of name servers.
Stores metadata for each RcodeZero anycast name server.
ip4,ip6: IPv4/IPv6 addresseshostname: DNS nameloc: Physical/data center location (in our case a 3 letter code), e.g. "mad"dsc_name: Long/nice name of the location, e.g. "Madrid"ns_type: ENUM (same as above)status: ENUM showing if the server is in production, maintenance, or disabled
Purpose: Define the DNS server fleet used for monitoring and SLA calculations.
Stores customer name server information.
ip: IP address of customer's name serverzone: Customer’s zone for which above IP address is allowed to send NOTIFYs (e.g., 'at' for customer nic.at)accountname: Customer/account label
Purpose: Track where customers send NOTIFYs from and how they're associated with zones.
Stores SLA metrics per zone and serial.
zone: Zone nameserial: Serial numbermin_lag,max_lag,avg_lag,median_lag,percentile_90_lag: Propagation delay statisticsns_count: Number of name servers used in calculationscalculated_at: When the metrics were computed or time of last update
Purpose: Evaluate SLA compliance of zone propagation.
- Logs the timestamp when a serial number becomes active.
- Detects and records propagation delays between DNS layers.
- Processes IPv4 and IPv6 NOTIFYs.
- Integrates with PostgreSQL for structured logging.
- Logs data in three customizable environments:
prod,test, anddev. - Designed for anycast and distributed DNS architectures.
- Clone the repository:
git clone https://github.com/nic-at/serial-logger
cd serial-logger
- Install the required dependencies:
sudo apt update
sudo apt install python3 python3-pip
pip install -r requirements.txt
-
Set up the database user: Create a PostgreSQL user 'serial_logger':
CREATE USER serial_logger WITH ENCRYPTED PASSWORD 'HEREYOURPASSWORD';Then add the user to pg_hba.conf.
-
Configure database credentials: Copy the sample credential file and edit it:
cp credentials.yaml.sample credentials.yaml
Edit credentials.yaml to match your environment.
- Set up the database:
Run the provided
python3 init_all_dbs.pyfile on your PostgreSQL server to create the required schema and tables. This will also GRANT proper permissions to theserial_loggeruser.
Run the daemon to start listening for NOTIFY messages:
python3 serial_logger.py
Make sure the daemon has access to:
- The PostgreSQL database
- Proper network ports (for receiving NOTIFYs)
- Logging paths
This project is licensed under the Apache License 2.0. See LICENSE for details.