opnsense-exporter icon indicating copy to clipboard operation
opnsense-exporter copied to clipboard

[BUG] - Parse Error on `api/unbound/diagnostics/stats`

Open kquinsland opened this issue 10 months ago • 11 comments

The exporter seems to be unhappy with something coming back from the API when inquiring about Unbound DNS.

ts=2024-03-30T04:11:09.033Z caller=collector.go:138 level=error msg="failed to update" component=collector collector_name=unbound_dns err="opnsense-client api call error: endpoint: api/unbound/diagnostics/stats; failed status code: 0; msg: error parsing  to int: strconv.Atoi: parsing \"\": invalid syntax" 

Versions

OPNsense 24.1.4-amd64
FreeBSD 13.2-RELEASE-p10
OpenSSL 3.0.13

Using exporter v0.0.3

kquinsland avatar Mar 30 '24 04:03 kquinsland

I do use Unbound so I can try to provide data from the API if the source of the error isn't obvious.

I wanted to ask if there's any plans to disable certain api end points?

E.G.: some --metric.disable=unbound flag to prevent the exporter from scraping that particular sub-system in opnsense?

Motivation:

  • It is possible to create a group with limited API permissions. E.G.: DENY access to /api/openvpn/export/* but ALLOW access to /api/openvpn/instances/*
  • It'd be nice to disable generation of some metrics to begin with so I don't have to use label/scrape configs to drop them

kquinsland avatar Mar 30 '24 04:03 kquinsland

There are already implemented switches to disable particular subsystems. You should just pass the flag or set the corresponding env to true. This is already mentioned in the README #Exporters

./opnsense-exporter --help

      --[no-]exporter.disable-arp-table
                                 Disable the scraping of the ARP table
                                 ($OPNSENSE_EXPORTER_DISABLE_ARP_TABLE)
      --[no-]exporter.disable-cron-table
                                 Disable the scraping of the cron table
                                 ($OPNSENSE_EXPORTER_DISABLE_CRON_TABLE)
      --[no-]exporter.disable-wireguard
                                 Disable the scraping of Wireguard service
                                 ($OPNSENSE_EXPORTER_DISABLE_WIREGUARD)

However the unbound disable is currently not implemented, but I will add flag for it shortly. It will be included in the next release which we can do after we merge your 2 PRs.

Thanks for the help.

ihatemodels avatar Mar 30 '24 20:03 ihatemodels

About the error, can you please provide the response from the API if possible clearing any sensitive data first. I suppose there is some "stringful" integer returned from the API.

ihatemodels avatar Mar 30 '24 20:03 ihatemodels

The unbound disable flag was introduced in #14

ihatemodels avatar Mar 30 '24 23:03 ihatemodels

About the error, can you please provide the response from the API if possible clearing any sensitive data first. I suppose there is some "stringful" integer returned from the API.

From browser dev tools, calls to:

/api/unbound/diagnostics/stats

Result in:

{
    "status": "ok",
    "data": {
        "thread0": {
            "num": {
                "queries": "58485",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42119",
                "cachemiss": "16366",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16366",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.102835",
                "max": "6",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.133630",
                    "median": "0.107612"
                }
            },
            "tcpusage": "0"
        },
        "thread1": {
            "num": {
                "queries": "58634",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42174",
                "cachemiss": "16460",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16460",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.105529",
                "max": "5",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.135741",
                    "median": "0.108197"
                }
            },
            "tcpusage": "0"
        },
        "thread2": {
            "num": {
                "queries": "58163",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42024",
                "cachemiss": "16139",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16139",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.102113",
                "max": "10",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.133746",
                    "median": "0.10868"
                }
            },
            "tcpusage": "0"
        },
        "thread3": {
            "num": {
                "queries": "58425",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42025",
                "cachemiss": "16400",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16400",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.101707",
                "max": "8",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.134549",
                    "median": "0.10744"
                }
            },
            "tcpusage": "0"
        },
        "thread4": {
            "num": {
                "queries": "58744",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42389",
                "cachemiss": "16355",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16354",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.103088",
                "max": "7",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "1",
                    "user": "1"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.134525",
                    "median": "0.107918"
                }
            },
            "tcpusage": "0"
        },
        "thread5": {
            "num": {
                "queries": "58633",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "42313",
                "cachemiss": "16320",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16320",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.106311",
                "max": "7",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.136922",
                    "median": "0.108184"
                }
            },
            "tcpusage": "0"
        },
        "thread6": {
            "num": {
                "queries": "58334",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "41927",
                "cachemiss": "16407",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "16407",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.101908",
                "max": "5",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.135397",
                    "median": "0.108311"
                }
            },
            "tcpusage": "0"
        },
        "thread7": {
            "num": {
                "queries": "64390",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "43171",
                "cachemiss": "21219",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "21219",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.0843584",
                "max": "7",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "0",
                    "user": "0"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.125493",
                    "median": "0.0987917"
                }
            },
            "tcpusage": "0"
        },
        "total": {
            "num": {
                "queries": "473808",
                "queries_ip_ratelimited": "0",
                "queries_cookie_valid": "0",
                "queries_cookie_client": "0",
                "queries_cookie_invalid": "0",
                "cachehits": "338142",
                "cachemiss": "135666",
                "prefetch": "0",
                "queries_timed_out": "0",
                "expired": "0",
                "recursivereplies": "135665",
                "dnscrypt": {
                    "crypted": "0",
                    "cert": "0",
                    "cleartext": "0",
                    "malformed": "0"
                }
            },
            "query": {
                "queue_time_us": {
                    "max": "0"
                }
            },
            "requestlist": {
                "avg": "0.100386",
                "max": "10",
                "overwritten": "0",
                "exceeded": "0",
                "current": {
                    "all": "1",
                    "user": "1"
                }
            },
            "recursion": {
                "time": {
                    "avg": "0.133456",
                    "median": "0.106892"
                }
            },
            "tcpusage": "0"
        },
        "time": {
            "now": "1711845897.176575",
            "up": "123456.933498",
            "elapsed": "123456.933498"
        }
    }
}

kquinsland avatar Mar 31 '24 00:03 kquinsland

Thanks. I will work on fixing unbound in the next release

ihatemodels avatar Apr 06 '24 22:04 ihatemodels

Stale issue message

github-actions[bot] avatar Jun 06 '24 10:06 github-actions[bot]

Stale issue message

github-actions[bot] avatar Aug 17 '24 10:08 github-actions[bot]

Bump. This error is still happening with opnsense-exporter v0.0.5 and OPNSense 24.7.2 (commit 8ffbc6387). I also included a sample of the api response.

/api/unbound/diagnostics/stats response
{
  "status": "ok",
  "data": {
    "thread0": {
      "num": {
        "queries": "562",
        "queries_ip_ratelimited": "0",
        "queries_cookie_valid": "0",
        "queries_cookie_client": "0",
        "queries_cookie_invalid": "0",
        "cachehits": "110",
        "cachemiss": "452",
        "prefetch": "0",
        "queries_timed_out": "0",
        "expired": "0",
        "recursivereplies": "452",
        "dnscrypt": {
          "crypted": "0",
          "cert": "0",
          "cleartext": "0",
          "malformed": "0"
        }
      },
      "query": {
        "queue_time_us": {
          "max": "0"
        }
      },
      "requestlist": {
        "avg": "0.389381",
        "max": "19",
        "overwritten": "0",
        "exceeded": "0",
        "current": {
          "all": "0",
          "user": "0"
        }
      },
      "recursion": {
        "time": {
          "avg": "0.060561",
          "median": "0.0419289"
        }
      },
      "tcpusage": "0"
    },
    "thread1": {
      "num": {
        "queries": "870",
        "queries_ip_ratelimited": "0",
        "queries_cookie_valid": "0",
        "queries_cookie_client": "0",
        "queries_cookie_invalid": "0",
        "cachehits": "441",
        "cachemiss": "429",
        "prefetch": "0",
        "queries_timed_out": "0",
        "expired": "0",
        "recursivereplies": "427",
        "dnscrypt": {
          "crypted": "0",
          "cert": "0",
          "cleartext": "0",
          "malformed": "0"
        }
      },
      "query": {
        "queue_time_us": {
          "max": "0"
        }
      },
      "requestlist": {
        "avg": "0.356643",
        "max": "17",
        "overwritten": "0",
        "exceeded": "2",
        "current": {
          "all": "0",
          "user": "0"
        }
      },
      "recursion": {
        "time": {
          "avg": "0.066897",
          "median": "0.0435346"
        }
      },
      "tcpusage": "0"
    },
    "thread2": {
      "num": {
        "queries": "723",
        "queries_ip_ratelimited": "0",
        "queries_cookie_valid": "0",
        "queries_cookie_client": "0",
        "queries_cookie_invalid": "0",
        "cachehits": "323",
        "cachemiss": "400",
        "prefetch": "0",
        "queries_timed_out": "0",
        "expired": "0",
        "recursivereplies": "400",
        "dnscrypt": {
          "crypted": "0",
          "cert": "0",
          "cleartext": "0",
          "malformed": "0"
        }
      },
      "query": {
        "queue_time_us": {
          "max": "0"
        }
      },
      "requestlist": {
        "avg": "0.28",
        "max": "15",
        "overwritten": "0",
        "exceeded": "0",
        "current": {
          "all": "0",
          "user": "0"
        }
      },
      "recursion": {
        "time": {
          "avg": "0.067971",
          "median": "0.0434678"
        }
      },
      "tcpusage": "0"
    },
    "total": {
      "num": {
        "queries": "2155",
        "queries_ip_ratelimited": "0",
        "queries_cookie_valid": "0",
        "queries_cookie_client": "0",
        "queries_cookie_invalid": "0",
        "cachehits": "874",
        "cachemiss": "1281",
        "prefetch": "0",
        "queries_timed_out": "0",
        "expired": "0",
        "recursivereplies": "1279",
        "dnscrypt": {
          "crypted": "0",
          "cert": "0",
          "cleartext": "0",
          "malformed": "0"
        }
      },
      "query": {
        "queue_time_us": {
          "max": "0"
        }
      },
      "requestlist": {
        "avg": "0.344262",
        "max": "19",
        "overwritten": "0",
        "exceeded": "2",
        "current": {
          "all": "0",
          "user": "0"
        }
      },
      "recursion": {
        "time": {
          "avg": "0.064993",
          "median": "0.0429771"
        }
      },
      "tcpusage": "0"
    },
    "time": {
      "now": "1724321248.745413",
      "up": "6739.805945",
      "elapsed": "6739.805945"
    }
  }
}

andresanches avatar Aug 22 '24 10:08 andresanches

Looking at opnsense/unbound_dns.go, it looks like the fields mem, num, unwanted, msg, rrset, infra, key, dnscrypt_shared_secret and dnscrypt_nonce are missing from the data object in the sample response of @andresanches.

Either these are (now) optional unbound stats or they got removed altogether.

Hope I didn't misinterpret any of the code @ihatemodels

Jannik-Hm avatar Aug 28 '24 23:08 Jannik-Hm

I may have found the solution:

Version: OPNsense 24.7.4_1-amd64

Browse to Services|Unbound DNS|Advanced, enable Extended Statistics, click Apply at bottom of page. That's it.

matthudsonatx avatar Sep 22 '24 21:09 matthudsonatx