Skip to content

OneBusAway Watchdog

sheldonabrown edited this page Sep 26, 2017 · 4 revisions

OneBusAway Watchdog is a simple framework for retrieving metrics about schedule and realtime data. When hosting OneBusAway, it is convenient to know information about the realtime data, and perhaps to even set alarms should the data fall outside what is expected.

Design

The idea is simple, for each metric of concern a webservice is created that exposes that data in a readily queryable format. Take for example a common issue with realtime feeds, counting the number of tripIds that were received but not matched to the current transit data bundle. By making a GET request on the webservice below:

onebusaway-watchdog-webapp/api/metric/realtime/trip/{agencyId}/unmatched

Returns:

{
  "currentTimestamp":1402402125238,
  "metricName":"unmatched-trips",
  "metricValue":1,
  "response":"SUCCESS",
  "errorMessage":null
}

Here, the agencyId is what is configured in the transit data bundle (e.g., 1). The metricValue property contains the response, indicating that for the last update from the realtime feed, we received one tripId that did not match to the bundle. The metricValue property should only be considered when the response property is populated with SUCCESS. Should the response not be a SUCCESS, the errorMessage property may be populated with a descriptive reason of the failure.

Metrics

Below is a table of webservices that have been implemented. Adding another metric is trivial, it simply requires extending MetricResource.

URL Result (metricValue) Notes
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/ping 1 if the service is up and the bundle loaded properly Sanity check on configuration
Agency - Schedule
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/schedule/agency/total Count of agencies loaded in current bundle See agency-id-list for more details
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/schedule/agency/id-list Array of agencyIds loaded from current bundle Exposes currently configured agencies.
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/schedule/agency/1/expiry-date-delta Number of days left before the data bundle for this agency expires Based on the bundle service dates for this agency - the latest service date is used as the expiration date for the bundle.
Trip - Schedule
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/schedule/trip/1/total Count of scheduled trips Per agency .
Agency - Realtime
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/agency/1/last-update-delta Seconds elapsed since last successful update An update may require non-zero update records to be considered successful
Trip - Realtime
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/trip/1/total Count of records included in the last realtime update Updates may contain multiple vehicles, do not associate this with trip or vehicle counts
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/trip/1/matched Count of realtime trips that were matched to scheduled trips (found in bundle) Counterpart to unmatched-trips
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/trip/1/unmatched Count of trip Ids not found in current bundle See unmatched-trip-ids for offending trips
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/trip/1/unmatched-ids Array of tripIds not found in bundle Search for these tripIds in agency provided bundle and report to agency.
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/trip/1/schedule-realtime-delta (Count of scheduled trips ) - (Count of realtime trips from last update) See buses-in-service-percent for percentage version of this metric
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/trip/1/buses-in-service-percent (count of realtime trips / count of scheduled trips) * 100 Reports percentages of realtime buses matched to schedule
Stop - Realtime
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/stop/1/unmatched Count of stop Ids not found in current bundle See unmatched-stop-ids for offending stopIds
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/stop/1/unmatched-ids Array of stopIds not found in bundle Search for these stopIds in agency provided bundle and report to agency
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/stop/1/matched Count of stop Ids matched to the current bundle
Location - Realtime
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/location/1/total Count of coordinates reported for Id
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/location/1/invalid Count of coordinates not inside agency bounding box Bounding box is defined from bundle
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/location/1/invalid-lat-lons Array of invalid lat/lons
Delta - Realtime
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/average-matched-trips Difference between current matched trips and long-term average
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/average-matched-trips-pct Percentage change of current matched trips against long-term average
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/average-unmatched-trips Difference between current unmatched trips and long-term average
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/average-unmatched-trips-pct Percentage change of current unmatched trips against long-term average
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/buses-in-service-pct Percentage change of buses in service pct against long-term average This is a percentage change in percentage values.
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/matched-stops-pct Percentage change of current matched stops against long-term average
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/unmatched-stops-pct Percentage change of current unmatched stops against long-term average
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/trip-total-pct Percentage change of current total trips against long-term average
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/trip-schedule-realtime-diff-pct Percentage change of current scheduled vs. realtime trips against long-term average
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/location-total-pct Percentage change of current total locations reported against long-term average
http://developer.onebusaway.org/onebusaway-watchdog-webapp/api/metric/realtime/delta/1/location-invalid-lat-lon-pct Percentage change of current total invalid locations reported against long-term average

Configuration

Create a data-sources.xml and place it in WEB-INF/classes (as is the OneBusAway convention). Here is an example.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">

<!--  define your data source here if required -->
    <bean id="dataSource"
          class="org.springframework.jndi.JndiObjectFactoryBean">
      <property name="jndiName"
                value="java:comp/env/jdbc/appDB"/>
      <property name="lookupOnStartup"
                value="true"/>
      <property name="cache"
                value="true"/>
      <property name="proxyInterface"
                value="javax.sql.DataSource"/>
      <property name="resourceRef"
                value="true" />
    </bean>

<!-- for each realtime feed define a realtime source with a unique id -->
    <bean id="feed1_avl" class="org.onebusaway.transit_data_federation.impl.realtime.gtfs_realtime.GtfsRealtimeSource">
        <property name="tripUpdatesUrl" value="http://localhost:7171/feed1/trip-updates" />
        <property name="vehiclePositionsUrl" value="http://localhost:7171/feed1/vehicle-positions" />
        <property name="refreshInterval" value="30"/>
        <!-- if you need to map this data source to a specific agency_id in your bundle use this -->
        <property name="agencyIds">
            <list>
                <value>1</value>
            </list>
        </property>
       <!-- a friendly name for the feed in logging -->
       <property name="feedId" value="feed1"/>
    </bean>
    <bean id="feed2_avl" class="org.onebusaway.transit_data_federation.impl.realtime.gtfs_realtime.GtfsRealtimeSource">
        <property name="tripUpdatesUrl" value="http://localhost:7272/feed2/trip-updates" />
        <property name="vehiclePositionsUrl" value="http://localhost:7272/feed2/vehicle-positions" />
        <property name="refreshInterval" value="30"/>
        <!-- if you need to map this data source to a specific agency_id in your bundle use this -->
        <property name="agencyIds">
            <list>
                <value>2</value>
            </list>
        </property>
       <!-- a friendly name for the feed in logging -->
       <property name="feedId" value="feed2"/>
    </bean>

<!-- configure where to store bundles -->
    <bean class="org.onebusaway.container.spring.SystemPropertyOverrideConfigurer">
      <property name="order" value="-2" />
      <property name="properties">
          <props>
              <prop key="bundlePath">/var/lib/oba/oba-watchodg-bundle</prop>
         </props>
      </property>
    </bean>

<!-- now define the metrics from the realtime sources defined above -->
        <bean id="metricConfiguration" class="org.onebusaway.watchdog.model.MetricConfiguration">
                <property name="transitDataService" ref="transitDataServiceImpl"/>
                <property name="monitoredDataSources">
                        <list>
                                <ref bean="feed1_avl" />
                                <ref bean="feed2_avl" />
                       </list>
                </property>
        </bean>

<!-- if you are running an admin server, configure the watchdog to retrieve bundles from it -->
<!--
    <bean id="httpServiceClient" class="org.onebusaway.transit_data_federation.util.HttpServiceClientImpl" >
      <constructor-arg type="java.lang.String" value="127.0.0.1"/>
      <constructor-arg type="java.lang.Integer" value="8080" />
      <constructor-arg type="java.lang.String" value="/api/" />
    </bean>

    <bean id="bundleManagementService" class="org.onebusaway.transit_data_federation.impl.bundle.BundleManagementServiceImpl">
      <property name="bundleStoreRoot" value="/var/lib/oba/oba-watchdog-bundle" />
      <property name="standaloneMode" value="false" />
    </bean>
-->


<!-- if you are manually deploying bundles follow this configuration -->
<!-- NOTE:  YOU CANNOT SHARE THE SAME BUNDLE BETWEEN OBA INSTANCES -->
<!--        YOU NEED TO COPY THE BUNDLE TO A NEW DIRECTORY -->
    <bean id="bundleManagementService" class="org.onebusaway.transit_data_federation.impl.bundle.BundleManagementServiceImpl">
      <property name="bundleStoreRoot" value="/var/lib/oba/oba-watchdog-bundle" />
      <property name="standaloneMode" value="true" />
    </bean>
</beans>