> ## Documentation Index > Fetch the complete documentation index at: https://bunny.net/docs/llms.txt > Use this file to discover all available pages before exploring further. # Helper Objects > The Scriptable DNS comes with a list of helper objects to help with various tasks needed for dynamic routing. This page contains the documentation for the helper objects. ## Monitoring The monitoring helper allows you to check and monitor the uptime status of an IP. This is useful for uptime checking when returning DNS records. It takes a single IP parameter that is then monitored in the background. ### How an IP's status is determined An IP is considered **online** if it responded to an ICMP ping in its most recent health check: * Each health check sends an ICMP ping with a 700 ms timeout, retrying up to 3 times. A single successful reply marks the IP as online; if all 3 attempts fail, it is marked as offline. * While an IP is being actively requested by your script, it is re-checked approximately every 10 seconds. IPs that are requested less often are checked less frequently (up to every 2 minutes), and IPs that are not requested for 3 days stop being monitored. * The first time an IP is requested, it is added to the background monitoring service and the DNS server synchronously waits for the initial check to complete. Subsequent requests return the cached status immediately. * Monitoring is performed independently by each DNS server, so the status reflects reachability from the DNS server handling the query. * Private and loopback addresses (`127.0.x.x`, `192.168.x.x`) and invalid IPs are always reported as offline. > [!NOTE] > > Monitoring is a network-level (ICMP) check only. It does not verify that an HTTP service or any specific port is responding. A server that responds to ping but has a failed application will still be reported as online. Make sure your servers allow inbound ICMP echo requests, otherwise they will always be reported as offline. ### Functions #### Monitoring.getStatus(IP: string): MonitoringStatus Returns the current status of the IP. ### MonitoringStatus The monitoring status object is returned by the `Monitoring.getStatus` helper and contains the monitoring information of a specific IP. | Field | Type | Description | | - | - | - | | `isOnline` | boolean | The current status of the IP (true: online, false: offline) | | `latency` | integer | The last measured latency from the DNS server to this IP | ```javascript theme={null} /* Example usage for Monitoring.getStatus Returns the A record for 222.222.222.222 if the IP is online, otherwise return 111.111.111.111 */ export default function handleQuery(query) { if (Monitoring.getStatus("222.222.222.222").isOnline == true) { return new ARecord("222.222.222.222", 30); } return new ARecord("111.111.111.111", 30); } ``` ## GeoDatabase GeoDatabase is a wrapper around a GeoDNS library. It allows you to easily look up the geo location of an IP address. ### Functions #### GeoDatabase.resolve(IP: string): GeoLocation Returns the [GeoLocation](https://bunny.net/docs/dns/scriptable/introduction.md#geolocation) result for the specified IP based on a GeoDNS database. ```javascript theme={null} /* Example usage for GeoDatabase.resolve Resolves the geo location for the IP 142.251.10.102 and returns the country code as a TXT record */ export default function handleQuery(query) { var location = GeoDatabase.resolve("142.251.10.102"); return new TxtRecord(location.country, 30); } ``` ## GeoDistance GeoDistance contains helper methods to help you calculate the distance between two geographical points. ### Functions #### GeoDistance.calculate(lat1: double, lon1: double, lat2: double, lon2: double): double Returns the geographical distance between two geographical locations based on latitude and longitude. #### GeoDistance.calculate(loc1: GeoLocation, loc2: GeoLocation): double Returns the geographical distance between two GeoLocation objects. #### GeoDistance.calculate(server: Server, location: GeoLocation): double Returns the geographical distance between a Server object and a GeoLocation object. ```javascript theme={null} /* Example usage for GeoDistance.calculate Calculates the distance between two points on the map and returns them as a TxtRecord value */ export default function handleQuery(query) { var distance = GeoDistance.calculate( 40.73061, -73.935242, // New York 50.110924, 8.682127, // Frankfurt ); return new TxtRecord( "Distance between New York and Frankfurt: " + distance, 30, ); } ``` ## RoutingEngine RoutingEngine helps with dynamic geographic routing, weight calculation, and round robin logic based on a list of servers. ### Functions #### RoutingEngine.getWeightedRandom(servers: Array\, onlineOnly: bool = false, applyWeight: bool = true): Server Returns one server from an array of servers based on a round robin weighted random principle, using each server's `weight`. If `onlineOnly` is set to `true`, servers that are offline (see [Monitoring](#how-an-ips-status-is-determined)) are skipped. If no servers are online, `null` is returned. ```javascript theme={null} /* Example usage for RoutingEngine.getWeightedRandom Returns one of the servers in a round robin fashion with the weights applied */ export default function handleQuery(query) { var servers = new Array( new Server("89.187.162.249", 40.69, -74.18, 100), new Server("89.187.162.249", 40.69, -74.18, 100), new Server("89.187.162.249", 40.69, -74.18, 75), new Server("89.187.162.249", 40.69, -74.18, 50), ); return RoutingEngine.getWeightedRandom( servers, true, // Skip offline servers ); } ``` #### RoutingEngine.getClosestServer(servers: Array\, location: GeoLocation, onlineOnly: bool = false, applyWeight: bool = true): Server Returns the server from an array of servers that is geographically closest to the given GeoLocation. If several servers are equally close, one of them is chosen using weighted round robin. If `onlineOnly` is set to `true`, servers that are offline (see [Monitoring](#how-an-ips-status-is-determined)) are skipped. **`onlineOnly` defaults to `false`**, so offline servers are only excluded when you pass `true` explicitly. > [!WARNING] > > If `onlineOnly` is `true` and none of the servers are online, no server is returned. Always provide a fallback record for this case. ```javascript theme={null} /* Example usage for RoutingEngine.getClosestServer Returns the geographically closest server to the client that sent the query */ export default function handleQuery(query) { var servers = new Array( new Server("89.187.162.249", 40.69, -74.18), new Server("89.187.162.248", 52.31, 4.76), new Server("89.187.162.247", -37.67, 144.85), new Server("89.187.162.246", 33.94, -118.41), ); return RoutingEngine.getClosestServer( servers, query.request.geoLocation, true, // Skip offline servers ); } ``` ## Server The Server object is used to pass or return server information to various other helper methods and does not contain any functionality by itself. > [!NOTE] > > The `online` constructor parameter is not used by `RoutingEngine`. Online status is always determined by the [Monitoring](#how-an-ips-status-is-determined) health check, so setting `online` to `false` will not remove a server from rotation. To take a server out of rotation, remove it from the array. ### Constructor ```typescript theme={null} constructor(ip: string, latitude: double = 0, longitude: double = 0, weight: int = 100, online: bool = true) ``` ### Fields | Field | Type | Description | | - | - | - | | `ip` | string | The IP of the server | | `latitude` | double | The geographical latitude of the server's location | | `longitude` | double | The geographical longitude of the server's location | | `weight` | int | The routing weight of the server in a weighted routing scenario | This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.