## Bug description

Since upgrading from 1.36.1 to 1.37.0, I've been seeing a high volume of errors in Sentry with the message "Object of type Decimal is not JSON serializable." The trace indicates that this is caused by capturing internal metrics, specifically from [`_capture` in `posthog/internal_metrics/__init__.py`](https://github.com/PostHog/posthog/blob/1.37.0/posthog/internal_metrics/__init__.py#L36). An example of an event that failed to serialize is

```python
{
  event: '$$pg_table_cache_hit_rate', 
  properties: {
    table: 'posthog_cohort', 
    value: Decimal('99.59125055236411842700')
  }
}
```

It seems the Postgres query added in #10392 is returning `Decimal`s and, although [`statshog` doesn't mind this](https://github.com/macobo/statshog/blob/master/statshog/client/base.py#L73), it doesn't work when dumping the metrics into Kafka as JSON.

Two possible solutions I see:
- Convert the `Decimal` to a float [here](https://github.com/PostHog/posthog/blob/97c327e3923943b5c226b058d59487a232d624fe/posthog/celery.py#L194):
```diff
- gauge("pg_table_cache_hit_rate", row[1], tags={"table": row[0]})
+ gauge("pg_table_cache_hit_rate", float(row[1]), tags={"table": row[0]})
```
- Subclass [`JSONEncoder`](https://docs.python.org/3/library/json.html#json.JSONEncoder) to handle the `Decimal` type and pass it [here](https://github.com/PostHog/posthog/blob/97c327e3923943b5c226b058d59487a232d624fe/posthog/api/capture.py#L50):
```diff
- "data": json.dumps(data),
+ "data": json.dumps(data, cls=NewJsonEncoder),
```

Because `json.dumps` is used in a variety of places, updating it to support decimals in just one place may cause surprising behavior if decimals end up elsewhere in PostHog, so my bias is towards simply casting the result of the query to a float. Another option would be to change _all_ uses of `json.dumps` to use a new encoder, but that adds future overhead that any new additions of `json.dumps` also need to remember to use the new encoder or else risk inconsistency. I'll wait for guidance from someone at PostHog before choosing a path forward and making a PR.

## How to reproduce

1. Set the `CAPTURE_INTERNAL_METRICS` environment variable to `"true"`

## Environment

- [ ] PostHog Cloud
- [X] self-hosted PostHog (ClickHouse-based), version/commit: 1.37.0
- [ ] self-hosted PostHog (Postgres-based, legacy), version/commit: _please provide_
posthog/celery.py
from posthog.tasks.calculate_event_property_usage import calculate_event_property_usage
    calculate_event_property_usage()
@app.task(ignore_result=True)
def calculate_billing_daily_usage():
    try:
        from multi_tenancy.tasks import compute_daily_usage_for_organizations  
    except ImportError:
        pass
    else:
        compute_daily_usage_for_organizations()
@app.task(ignore_result=True)
def send_first_ingestion_reminder_emails():
    from posthog.tasks.email import send_first_ingestion_reminder_emails
    send_first_ingestion_reminder_emails()
@app.task(ignore_result=True)
def send_second_ingestion_reminder_emails():
    from posthog.tasks.email import send_second_ingestion_reminder_emails
    send_second_ingestion_reminder_emails()
@app.task(ignore_result=True)
def sync_all_organization_available_features():
    from posthog.tasks.sync_all_organization_available_features import sync_all_organization_available_features
    sync_all_organization_available_features()
@app.task(ignore_result=False, track_started=True, max_retries=0)
def check_async_migration_health():
    from posthog.tasks.async_migrations import check_async_migration_health
    check_async_migration_health()
@app.task(ignore_result=True)
def verify_persons_data_in_sync():