## 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
continue
                    gauge(f"pg_plugin_server_query_{key}", value, tags={"query_type": row_dictionary["query_type"]})
        except:
            
            pass
CLICKHOUSE_TABLES = [
    "events",
    "person",
    "person_distinct_id",
    "person_distinct_id2",
    "session_recording_events",
]
if settings.CLICKHOUSE_REPLICATION:
    CLICKHOUSE_TABLES.extend(
        ["sharded_events", "sharded_session_recording_events",]
    )
@app.task(ignore_result=True)
def clickhouse_lag():
    from posthog.client import sync_execute
    from posthog.internal_metrics import gauge
    for table in CLICKHOUSE_TABLES:
        try:
            QUERY = """select max(_timestamp) observed_ts, now() now_ts, now() - max(_timestamp) as lag from {table};"""
            query = QUERY.format(table=table)
            lag = sync_execute(query)[0][2]
            gauge("posthog_celery_clickhouse__table_lag_seconds", lag, tags={"table": table})
        except:
            pass
@app.task(ignore_result=True)
def ingestion_lag():