## 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.models.team.util import delete_clickhouse_data_for_deleted_teams
    delete_clickhouse_data_for_deleted_teams()
@app.task(ignore_result=True)
def redis_celery_queue_depth():
    from posthog.internal_metrics import gauge
    try:
        llen = get_client().llen("celery")
        gauge(f"posthog_celery_queue_depth", llen)
    except:
        
        
        return
@app.task(ignore_result=True)
def update_event_partitions():
    with connection.cursor() as cursor:
        cursor.execute(
            "DO $$ BEGIN IF (SELECT exists(select * from pg_proc where proname = 'update_partitions')) THEN PERFORM update_partitions(); END IF; END $$"
        )
@app.task(ignore_result=True)
def clean_stale_partials():
    """Clean stale (meaning older than 7 days) partial social auth sessions."""
    from social_django.models import Partial
    Partial.objects.filter(timestamp__lt=timezone.now() - timezone.timedelta(7)).delete()
@app.task(ignore_result=True)
def status_report():