Skip to content

Commit eab025f

Browse files
chitalianJustin Torreclaude
authored
fix: always log metadata for free tier exceeded, skip only S3 bodies (#5545)
* fix: PTB should read bodies from S3 even when freeLimitExceeded PTB requests always store bodies to S3 for billing purposes, so Jawn should not treat them as "not_stored_exceeded_free". Only non-PTB requests with freeLimitExceeded should skip S3 body reading. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: always log metadata to ClickHouse, skip only S3 bodies for exceeded free tier - Remove early exit that skipped Kafka logging entirely - Metadata (request count, latency, tokens, cost) always logged to ClickHouse - Only S3 body storage is skipped for non-PTB exceeded free tier - This allows tracking request volume for exceeded orgs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: PTB with free tier exceeded skips S3 only if usage extraction succeeded - PTB + got usage: skip S3 bodies (we have what we need for billing) - PTB + failed to get usage: store S3 bodies (Jawn needs to extract) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: fix outdated comment about early exit Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Justin Torre <justin@Justins-MacBook-Pro.local> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 4420800 commit eab025f

File tree

2 files changed

+18
-16
lines changed

2 files changed

+18
-16
lines changed

valhalla/jawn/src/lib/handlers/LoggingHandler.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,12 @@ export class LoggingHandler extends AbstractLogHandler {
172172

173173
context.sizeBytes = size ?? 0;
174174
// Determine storage location:
175-
// 1. If free tier limit exceeded, bodies were not stored
175+
// 1. If free tier limit exceeded AND not PTB, bodies were not stored
176176
// 2. If size is small enough, use clickhouse
177177
// 3. Otherwise use s3
178-
if (context.message.heliconeMeta.freeLimitExceeded) {
178+
// Note: PTB always stores bodies to S3 for billing purposes
179+
const isPTB = context.message.heliconeMeta.isPassthroughBilling;
180+
if (context.message.heliconeMeta.freeLimitExceeded && !isPTB) {
179181
context.storageLocation = "not_stored_exceeded_free";
180182
} else {
181183
context.storageLocation =

worker/src/lib/dbLogger/DBLoggable.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -797,14 +797,9 @@ export class DBLoggable {
797797
org.data.tier === "free" && org.data.freeLimitExceeded === currentMonth;
798798
const isPassthroughBilling = this.request.escrowInfo ? true : false;
799799

800-
// Skip logging entirely if free limit exceeded and not PTB
801-
// This saves processing - we don't need to extract usage or send to Kafka
802-
if (freeLimitExceeded && !isPassthroughBilling) {
803-
console.log(
804-
`[FreeTierLimit] Skipping logging entirely for org ${authParams.organizationId} - free tier limit exceeded and not PTB`
805-
);
806-
return ok(null);
807-
}
800+
// Note: We always log metadata to Kafka/ClickHouse even when free limit exceeded
801+
// This allows tracking request volume for exceeded orgs
802+
// We just skip S3 body storage for non-PTB exceeded requests
808803

809804
const { body: rawResponseBody, endTime: responseEndTime } =
810805
await this.response.getResponseBody();
@@ -840,13 +835,19 @@ export class DBLoggable {
840835
failedToGetUsage = true;
841836
}
842837

843-
// Skip S3 storage only if BOTH request and response are omitted
844-
// If only one is omitted, still store to S3 - Jawn will respect the omit flags
845-
// IMPORTANT: For PTB, if we failed to get usage, always store to S3 so Jawn can extract it for billing
846-
const skipS3Storage =
838+
// Skip S3 storage if:
839+
// 1. Free tier limit exceeded AND (not PTB OR we got usage successfully)
840+
// - Non-PTB: always skip bodies
841+
// - PTB with usage: skip bodies (we have what we need for billing)
842+
// - PTB without usage: store bodies (Jawn needs to extract for billing)
843+
// 2. Both omit headers are set (but not if PTB failed to get usage)
844+
const skipS3ForFreeTier =
845+
freeLimitExceeded && (!isPassthroughBilling || !failedToGetUsage);
846+
const skipS3ForOmitHeaders =
847847
!(isPassthroughBilling && failedToGetUsage) &&
848848
requestHeaders?.omitHeaders?.omitRequest === true &&
849849
requestHeaders?.omitHeaders?.omitResponse === true;
850+
const skipS3Storage = skipS3ForFreeTier || skipS3ForOmitHeaders;
850851

851852
if (S3_ENABLED === "true" && !skipS3Storage) {
852853
try {
@@ -952,8 +953,7 @@ export class DBLoggable {
952953
this.request.attempt?.endpoint.providerModelId ?? undefined,
953954
stripeCustomerId: requestHeaders.stripeCustomerId ?? undefined,
954955
aiGatewayBodyMapping: aiGatewayBodyMapping ?? undefined,
955-
// Note: If we reach here with freeLimitExceeded=true, it means PTB is enabled
956-
// (non-PTB exceeded requests exit early above)
956+
// Pass freeLimitExceeded to Jawn so it knows bodies may not be in S3
957957
freeLimitExceeded: freeLimitExceeded ? true : undefined,
958958
},
959959
log: {

0 commit comments

Comments
 (0)