{"id":7889,"date":"2019-01-08T14:05:46","date_gmt":"2019-01-08T18:05:46","guid":{"rendered":"http:\/\/dougmcclure.net\/blog\/?p=7889"},"modified":"2019-01-30T20:51:37","modified_gmt":"2019-01-31T00:51:37","slug":"nagios-xi-pagerduty-the-path-to-a-monitoring-service","status":"publish","type":"post","link":"https:\/\/dougmcclure.net\/blog\/2019\/01\/nagios-xi-pagerduty-the-path-to-a-monitoring-service\/","title":{"rendered":"Nagios XI &#038; PagerDuty: The path to a \u201cMonitoring Service\u201d"},"content":{"rendered":"\n<p>Nagios (Core\/XI) is one of the top 5 most widely integrated tools across PagerDuty\u2019s 10K+ customers providing fundamental host and service monitoring and alerting capabilities. During my time here at PagerDuty, I\u2019ve had the opportunity to work with very very large and <g class=\"gr_ gr_10 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling multiReplace\" id=\"10\" data-gr-id=\"10\">well established<\/g> enterprises and the latest up and coming start-ups \/ DevOps teams all still relying on good old Nagios monitoring for their infrastructure. I remember the SysAdmin teams I worked with back in the 2000\u2019s using early versions of Nagios, it\u2019s certainly been around for a long time and works well for the basics.<\/p>\n\n\n\n<p>From what I\u2019ve seen, many of PagerDuty\u2019s customers take a \u201cset it and forget it\u201d approach in their integrations. They\u2019ve followed the super simple integration guide (e.g. <a rel=\"noreferrer noopener\" aria-label=\"Nagios XI (opens in a new tab)\" href=\"https:\/\/www.pagerduty.com\/docs\/guides\/nagios-xi-integration-guide\" target=\"_blank\">Nagios XI<\/a>) and created a \u201cmonitoring service\u201d in PagerDuty. In this configuration, Nagios host or service templates are updated to send all Nagios alerts to one single PagerDuty service integration key (the \u201cPagerDuty Contact\u201d <g class=\"gr_ gr_7 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del\" id=\"7\" data-gr-id=\"7\">pager<\/g> number) and ALL alerts are sent to PagerDuty notifying on-call responders of the latest Nagios alert. The key here with this default configuration is that everything monitored in Nagios whether it is a Windows or Linux server, network device, database or web server, all of the alert notifications are sent to the same \u201cPagerDuty Contact\u201d (the PagerDuty service) and notify whoever is on that single service&#8217;s escalation policy. Most integration guides include an FAQ section at the bottom&nbsp;of the guide with pointers on extending the default integration to address this, but few seem to go down this path. This default configuration pattern isn\u2019t the best practice for an ideal operational response and use of PagerDuty.<\/p>\n\n\n\n<p>When I say \u201cset it and forget it\u201d, what I\u2019m really saying is that the integration well-established up so quickly and \u2018just works\u2019, that teams just <g class=\"gr_ gr_24 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar multiReplace\" id=\"24\" data-gr-id=\"24\">move<\/g> on to the next thing vying for their attention in their environment and accept what they have as \u2018good enough\u2019.&nbsp; Some teams have more maturity within their team\/processes or have dedicated FTEs solely responsible for the care and feeding of their Nagios configurations as part of their configuration management, CI\/CD or similar release process.&nbsp; Over time, the daily demands of the business and ops prohibit going back and optimizing the Nagios to PagerDuty integration to properly address many of the shortcomings in the default integration guide available today.<\/p>\n\n\n\n<p>What I\u2019d like to drill in on here are a few of these default configurations and their resulting alert, incident and reporting artifacts within PagerDuty and the operational implications over the next few blog posts how to move beyond the defaults to a best practice configuration in both Nagios and PagerDuty.<\/p>\n\n\n\n<p><strong>The Guts of the Nagios XI &#8211; PagerDuty Default Integration<\/strong><\/p>\n\n\n\n<p>The core of the PagerDuty &#8211; Nagios XI integration comes down to two parts, the Nagios XI Contact configuration and the Nagios XI Command (and associated pd-nagios python script). Essentially, the contact defines the alert notification conditions and whom (or what) to send the notification details to and the command receives the alert notification metadata (via Nagios macros) and passes this data into the pd-nagios script resulting in a post to the PagerDuty Event API v1.<\/p>\n\n\n\n<p>In the service notification example below, when a service alert is triggered on a host, the configured contact alert conditions are evaluated the service notification command is executed. The default \u2018notify-service-by-pagerduty\u2019 command is called passing in a number of parameters to the pd-nagios python script.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"2884\" height=\"140\" src=\"http:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-8.43.05-AM.png\" alt=\"\" class=\"wp-image-7891\" srcset=\"https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-8.43.05-AM.png 2884w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-8.43.05-AM-300x15.png 300w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-8.43.05-AM-768x37.png 768w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-8.43.05-AM-1024x50.png 1024w\" sizes=\"auto, (max-width: 2884px) 100vw, 2884px\" \/><\/figure>\n\n\n\n<p><strong>Command Line:<\/strong> \/usr\/share\/pdagent-integrations\/bin\/pd-nagios -n service -k $CONTACTPAGER$ -t &#8220;$NOTIFICATIONTYPE$&#8221; -f SERVICEDESC=&#8221;$SERVICEDESC$&#8221; -f SERVICESTATE=&#8221;$SERVICESTATE$&#8221; -f HOSTNAME=&#8221;$HOSTNAME$&#8221; -f SERVICEOUTPUT=&#8221;$SERVICEOUTPUT$&#8221;<\/p>\n\n\n\n<p>This simple Nagios command and associated executable script and parameters <g class=\"gr_ gr_4 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar multiReplace\" id=\"4\" data-gr-id=\"4\">is<\/g> where everything comes together. Let&#8217;s review this in more detail.<\/p>\n\n\n\n<p><strong>-n [service|host]: notification_type:<\/strong> This parameter is used to signify if this is a service or host notification from Nagios. It&#8217;s used in the <g class=\"gr_ gr_7 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace\" id=\"7\" data-gr-id=\"7\">pd<\/g>&#8211;<g class=\"gr_ gr_6 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace\" id=\"6\" data-gr-id=\"6\">nagios<\/g> script to set up which macro values are mapped into PagerDuty event payload fields. This value is displayed in the alert key field.<\/p>\n\n\n\n<p><strong>-k $CONTACTPAGER$<\/strong>: This is the <g class=\"gr_ gr_52 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del\" id=\"52\" data-gr-id=\"52\">pager<\/g> number\/address for the Nagios contact. This value is taken from the&nbsp;<em><g class=\"gr_ gr_6 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del\" id=\"6\" data-gr-id=\"6\"><a rel=\"noreferrer noopener\" aria-label=\"pager (opens in a new tab)\" href=\"https:\/\/assets.nagios.com\/downloads\/nagioscore\/docs\/nagioscore\/3\/en\/macrolist.html#contactpager?\" target=\"_blank\">pager<\/a><\/g><\/em>&nbsp;directive in the&nbsp;<a href=\"https:\/\/assets.nagios.com\/downloads\/nagioscore\/docs\/nagioscore\/3\/en\/objectdefinitions.html#contact\">contact definition<\/a>. &nbsp;This macro value maps into the PagerDuty <a rel=\"noreferrer noopener\" aria-label=\"Event API v1 (opens in a new tab)\" href=\"https:\/\/v2.developer.pagerduty.com\/docs\/events-api?\" target=\"_blank\">Event API v1<\/a>  <strong>service_key<\/strong> field and represents the &#8220;Integration Key&#8221; for the Nagios XI integration configured on the PagerDuty service. This could also be an integration key for a Custom Event Transformer (CET) or the Global Event Routing API key. Set in step #12 of the PagerDuty &#8211; Nagios XI integration guide.<\/p>\n\n\n\n<p><strong>-t $NOTIFICATIONTYPE$<\/strong>: A string identifying the type of <a rel=\"noreferrer noopener\" aria-label=\"notification (opens in a new tab)\" href=\"https:\/\/assets.nagios.com\/downloads\/nagioscore\/docs\/nagioscore\/3\/en\/macrolist.html#notificationtype \" target=\"_blank\">notification<\/a> that is being sent (&#8220;PROBLEM&#8221;, &#8220;RECOVERY&#8221;, &#8220;ACKNOWLEDGEMENT&#8221;, &#8220;FLAPPINGSTART&#8221;, &#8220;FLAPPINGSTOP&#8221;, &#8220;FLAPPINGDISABLED&#8221;, &#8220;DOWNTIMESTART&#8221;, &#8220;DOWNTIMEEND&#8221;, or &#8220;DOWNTIMECANCELLED&#8221;). This macro value maps into the PagerDuty <a rel=\"noreferrer noopener\" href=\"https:\/\/v2.developer.pagerduty.com\/docs\/events-api%EF%BB%BF\" target=\"_blank\">Event API v1<\/a> <strong>event_type<\/strong> field. Nagios XI \u201cPROBLEM\u201d maps to event_type \u2018trigger\u2019, \u201cACKNOWLEDGEMENT\u201d maps to event_type \u2018acknowledge\u2019 and \u201cRECOVERY\u201d maps to event_type \u2018resolve\u2019.<\/p>\n\n\n\n<p><strong>-f $SERVICEDESC$<\/strong>: The long name\/description of the service (i.e. &#8220;Main Website&#8221;). This value is taken from the&nbsp;<em><a rel=\"noreferrer noopener\" aria-label=\"service_description (opens in a new tab)\" href=\"https:\/\/assets.nagios.com\/downloads\/nagioscore\/docs\/nagioscore\/3\/en\/macrolist.html#servicedesc\" target=\"_blank\">service_description<\/a><\/em>&nbsp;directive of the&nbsp;<a href=\"https:\/\/assets.nagios.com\/downloads\/nagioscore\/docs\/nagioscore\/3\/en\/objectdefinitions.html#service\">service definition<\/a>. This macro value is used in the PagerDuty incident description, alert key, service and custom details fields.<\/p>\n\n\n\n<p><strong>-f $SERVICESTATE$<\/strong>: A string indicating the <a rel=\"noreferrer noopener\" aria-label=\"current state (opens in a new tab)\" href=\"https:\/\/assets.nagios.com\/downloads\/nagioscore\/docs\/nagioscore\/3\/en\/macrolist.html#servicestate?\" target=\"_blank\">current state<\/a> of the service (&#8220;OK&#8221;, &#8220;WARNING&#8221;, &#8220;UNKNOWN&#8221;, or &#8220;CRITICAL&#8221;).  This macro value maps into the PagerDuty <a rel=\"noreferrer noopener\" href=\"https:\/\/v2.developer.pagerduty.com\/docs\/events-api%EF%BB%BF\" target=\"_blank\">Event API v1<\/a> <strong>severity<\/strong> field and is used in the PagerDuty incident description, severity, state and custom details fields.<\/p>\n\n\n\n<p><strong>-f $HOSTNAME$<\/strong>: Short name for the host (i.e. &#8220;<g class=\"gr_ gr_6 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling\" id=\"6\" data-gr-id=\"6\">biglinuxbox<\/g>&#8220;). This value is taken from the&nbsp;<em><a rel=\"noreferrer noopener\" aria-label=\"host_name (opens in a new tab)\" href=\"https:\/\/assets.nagios.com\/downloads\/nagioscore\/docs\/nagioscore\/3\/en\/macrolist.html#hostname\" target=\"_blank\">host_name<\/a><\/em>&nbsp;directive in the&nbsp;<a href=\"https:\/\/assets.nagios.com\/downloads\/nagioscore\/docs\/nagioscore\/3\/en\/objectdefinitions.html#host\">host definition<\/a>. This macro value is used in the PagerDuty incident description, alert key, source, host and custom details fields.<\/p>\n\n\n\n<p><strong>-f $SERVICEOUTPUT$<\/strong>: The first line of text <a rel=\"noreferrer noopener\" aria-label=\"output (opens in a new tab)\" href=\"https:\/\/assets.nagios.com\/downloads\/nagioscore\/docs\/nagioscore\/3\/en\/macrolist.html#serviceoutput\" target=\"_blank\">output<\/a> from the last service check (i.e. &#8220;Ping OK&#8221;).  This macro value is used in the PagerDuty incident service output and custom details fields.<\/p>\n\n\n\n<p><strong>The results of the Nagios XI &#8211; PagerDuty Default Integration<\/strong><\/p>\n\n\n\n<p>Let&#8217;s explore how this default Nagios XI &#8211; PagerDuty integration looks as seen in various places the alert and incident could be displayed. We&#8217;ll use this Nagios XI alert as the example.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"852\" src=\"http:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.08.31-AM-1024x852.png\" alt=\"\" class=\"wp-image-7894\" srcset=\"https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.08.31-AM-1024x852.png 1024w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.08.31-AM-300x250.png 300w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.08.31-AM-768x639.png 768w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.08.31-AM.png 1600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This Nagios XI disk alert will trigger the &#8216;notify-service-by-pagerduty&#8217; command and pass the macro values to the PagerDuty Event API v1 resulting in a new PagerDuty alert.<\/p>\n\n\n\n<p>This is the resulting PagerDuty alert display within the Alert tab. Note that I customized the column display to show the additional columns that could display alert information.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.22.46-AM-1024x530.png\" alt=\"\" class=\"wp-image-7895\" srcset=\"https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.22.46-AM-1024x530.png 1024w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.22.46-AM-300x155.png 300w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.22.46-AM-768x398.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>If &#8220;View Message&#8221; is clicked on in the lower left corner, a portion of the PagerDuty Event API v1 payload can be seen.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"526\" src=\"http:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.24.37-AM-1024x526.png\" alt=\"\" class=\"wp-image-7896\" srcset=\"https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.24.37-AM-1024x526.png 1024w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.24.37-AM-300x154.png 300w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.24.37-AM-768x395.png 768w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.24.37-AM.png 1856w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>By clicking on the alert summary I can open the alert&#8217;s detailed display.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"804\" height=\"1024\" src=\"http:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.27.12-AM-804x1024.png\" alt=\"\" class=\"wp-image-7899\" srcset=\"https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.27.12-AM-804x1024.png 804w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.27.12-AM-235x300.png 235w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.27.12-AM-768x979.png 768w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.27.12-AM.png 1466w\" sizes=\"auto, (max-width: 804px) 100vw, 804px\" \/><\/figure>\n\n\n\n<p>By clicking on the link next to &#8220;Related to Incident:&#8221;, the PagerDuty incident details is displayed.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"896\" src=\"http:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.30.17-AM-1024x896.png\" alt=\"\" class=\"wp-image-7900\" srcset=\"https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.30.17-AM-1024x896.png 1024w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.30.17-AM-300x262.png 300w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.30.17-AM-768x672.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>If the PagerDuty user has configured their notification preferences to receive email, this is what they would be sent.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"886\" src=\"http:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.32.52-AM-1024x886.png\" alt=\"\" class=\"wp-image-7901\" srcset=\"https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.32.52-AM-1024x886.png 1024w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.32.52-AM-300x260.png 300w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.32.52-AM-768x665.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>If the PagerDuty user has configured their notification preferences to receive push notifications on the PagerDuty mobile app, this is what they&#8217;d see for the incident and alert detail.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"843\" src=\"http:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.35.01-AM-1024x843.png\" alt=\"\" class=\"wp-image-7902\" srcset=\"https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.35.01-AM-1024x843.png 1024w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.35.01-AM-300x247.png 300w, https:\/\/dougmcclure.net\/blog\/wp-content\/uploads\/2019\/01\/Screen-Shot-2019-01-08-at-9.35.01-AM-768x632.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In the next blog post, I&#8217;ll call out some of the reasons why running in this default configuration isn&#8217;t best practice and how this impacts an ops team&#8217;s response when using PagerDuty. I&#8217;ll also lay out the next steps that can be taken to move towards better practices when integrating Nagios with PagerDuty.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nagios (Core\/XI) is one of the top 5 most widely integrated tools across PagerDuty\u2019s 10K+ customers providing fundamental host and service monitoring and alerting capabilities. During my time here at PagerDuty, I\u2019ve had the opportunity to work with very very large and well established enterprises and the latest up and coming start-ups \/ DevOps teams [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1084,1077,1078],"tags":[931,929,523,991,1073,1072],"class_list":{"0":"post-7889","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-integrations","7":"category-pagerduty","8":"category-pagerduty-best-practices","9":"tag-best-practices","10":"tag-events","11":"tag-integrations","12":"tag-monitoring","13":"tag-nagios-xi","14":"tag-pagerduty"},"_links":{"self":[{"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/posts\/7889","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/comments?post=7889"}],"version-history":[{"count":5,"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/posts\/7889\/revisions"}],"predecessor-version":[{"id":7910,"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/posts\/7889\/revisions\/7910"}],"wp:attachment":[{"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/media?parent=7889"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/categories?post=7889"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dougmcclure.net\/blog\/wp-json\/wp\/v2\/tags?post=7889"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}