Hello everyone;
I’ve noticed that Vercel runtime logs don’t show internal API request or related function console logs. I created a cron job for my project that calls the /api/fetch-transaction
endpoint to fetch transaction data from BSC Scan and cache it on the server daily. I also use CRON_SECRET
for security with middleware, and it is working correctly.
Project Details:
- Framework: Next.js 14
- Run engine: Node.js 20
Problem Occurrence:
- Situation: Cron-job making internal API calls.
However, when I build the cron job endpoint, the fetch logs appear correctly in the build logs:
[14:27:10.135] Collecting page data ...
[14:27:13.581] Generating static pages (0/16) ...
[14:27:13.879] Generating static pages (4/16)
[14:27:14.132] Cron job endpoint called
[14:27:14.133] Cron job started
[14:27:14.141] Generating static pages (8/16)
[14:27:14.394] Fetching transactions for testnet address: 0x70aF4c67f16019C13516D814aAf9A6aD74CFd2F4
[14:27:14.394] Fetching transactions from URL: https://tokens-ui-nextjs-q1a2qsube-tahsins-projects-0ae86724.vercel.app/api/fetch-transactions?contractaddress=0x70aF4c67f16019C13516D814aAf9A6aD74CFd2F4&testnet=true&allTx=true&cleanCache=true
[14:27:15.058] Generating static pages (12/16)
[14:27:15.063] Response status: 200
[14:27:15.063] Transactions fetched for 0x70aF4c67f16019C13516D814aAf9A6aD74CFd2F4
[14:27:15.063] Successfully fetched transactions for testnet address: 0x70aF4c67f16019C13516D814aAf9A6aD74CFd2F4
[14:27:15.520] Fetching transactions for testnet address: 0x9eB947Be4de53332022Edbc51528d33EB5D80f94
[14:27:15.520] Fetching transactions from URL: https://tokens-ui-nextjs-q1a2qsube-tahsins-projects-0ae86724.vercel.app/api/fetch-transactions?contractaddress=0x9eB947Be4de53332022Edbc51528d33EB5D80f94&testnet=true&allTx=true&cleanCache=true
[14:27:15.952] Response status: 200
[14:27:15.952] Transactions fetched for 0x9eB947Be4de53332022Edbc51528d33EB5D80f94
[14:27:15.952] Successfully fetched transactions for testnet address: 0x9eB947Be4de53332022Edbc51528d33EB5D80f94
[14:27:16.411] Fetching transactions for testnet address: 0xdC7B8A96e0Ce131E1C0562BB0Cf35F12a0D1b6d6
[14:27:16.411] Fetching transactions from URL: https://tokens-ui-nextjs-q1a2qsube-tahsins-projects-0ae86724.vercel.app/api/fetch-transactions?contractaddress=0xdC7B8A96e0Ce131E1C0562BB0Cf35F12a0D1b6d6&testnet=true&allTx=true&cleanCache=true
[14:27:16.888] Response status: 200
[14:27:16.889] Transactions fetched for 0xdC7B8A96e0Ce131E1C0562BB0Cf35F12a0D1b6d6
[14:27:16.889] Successfully fetched transactions for testnet address: 0xdC7B8A96e0Ce131E1C0562BB0Cf35F12a0D1b6d6
[14:27:17.364] Fetching transactions for testnet address: 0x891F52b828C7242dC95D38903D387D7d12e33CB2
[14:27:17.365] Fetching transactions from URL: https://tokens-ui-nextjs-q1a2qsube-tahsins-projects-0ae86724.vercel.app/api/fetch-transactions?contractaddress=0x891F52b828C7242dC95D38903D387D7d12e33CB2&testnet=true&allTx=true&cleanCache=true
[14:27:17.656] Response status: 200
[14:27:17.656] Transactions fetched for 0x891F52b828C7242dC95D38903D387D7d12e33CB2
[14:27:17.656] Successfully fetched transactions for testnet address: 0x891F52b828C7242dC95D38903D387D7d12e33CB2
[14:27:18.120] Fetching transactions for mainnet address: 0x5D5c5c1d14FaF8Ff704295b2F502dAA9D06799a0
[14:27:18.120] Fetching transactions from URL: https://tokens-ui-nextjs-q1a2qsube-tahsins-projects-0ae86724.vercel.app/api/fetch-transactions?contractaddress=0x5D5c5c1d14FaF8Ff704295b2F502dAA9D06799a0&testnet=false&allTx=true&cleanCache=true
[14:27:18.988] Response status: 200
[14:27:18.988] Transactions fetched for 0x5D5c5c1d14FaF8Ff704295b2F502dAA9D06799a0
[14:27:18.988] Successfully fetched transactions for mainnet address: 0x5D5c5c1d14FaF8Ff704295b2F502dAA9D06799a0
[14:27:18.988] Fetching transactions for mainnet address: 0xbe2D8AC2A370972C4328BED520b224C3903A4941
[14:27:18.988] Fetching transactions from URL: https://tokens-ui-nextjs-q1a2qsube-tahsins-projects-0ae86724.vercel.app/api/fetch-transactions?contractaddress=0xbe2D8AC2A370972C4328BED520b224C3903A4941&testnet=false&allTx=true&cleanCache=true
[14:27:19.037] Response status: 200
[14:27:19.037] Transactions fetched for 0xbe2D8AC2A370972C4328BED520b224C3903A4941
[14:27:19.037] Successfully fetched transactions for mainnet address: 0xbe2D8AC2A370972C4328BED520b224C3903A4941
[14:27:19.537] Fetching transactions for mainnet address: 0x55b6d96126879Fe99ca1f57A05F81941d0932F9C
[14:27:19.538] Fetching transactions from URL: https://tokens-ui-nextjs-q1a2qsube-tahsins-projects-0ae86724.vercel.app/api/fetch-transactions?contractaddress=0x55b6d96126879Fe99ca1f57A05F81941d0932F9C&testnet=false&allTx=true&cleanCache=true
[14:27:19.967] Response status: 200
[14:27:19.967] Transactions fetched for 0x55b6d96126879Fe99ca1f57A05F81941d0932F9C
[14:27:19.967] Successfully fetched transactions for mainnet address: 0x55b6d96126879Fe99ca1f57A05F81941d0932F9C
[14:27:20.722] Fetching transactions for mainnet address: 0xF9f594D86AEF52644473edC43B6dC9656E4fD2Ce
[14:27:20.722] Fetching transactions from URL: https://tokens-ui-nextjs-q1a2qsube-tahsins-projects-0ae86724.vercel.app/api/fetch-transactions?contractaddress=0xF9f594D86AEF52644473edC43B6dC9656E4fD2Ce&testnet=false&allTx=true&cleanCache=true
[14:27:20.722] Response status: 200
[14:27:20.722] Transactions fetched for 0xF9f594D86AEF52644473edC43B6dC9656E4fD2Ce
[14:27:20.722] Successfully fetched transactions for mainnet address: 0xF9f594D86AEF52644473edC43B6dC9656E4fD2Ce
[14:27:21.060] Cron job finished
[14:27:21.061] Cron job completed successfully: Cron jobs completed with the following results:
[14:27:21.061] Testnet address 0x70aF4c67f16019C13516D814aAf9A6aD74CFd2F4: Transactions fetched for 0x70aF4c67f16019C13516D814aAf9A6aD74CFd2F4
[14:27:21.061] Testnet address 0x9eB947Be4de53332022Edbc51528d33EB5D80f94: Transactions fetched for 0x9eB947Be4de53332022Edbc51528d33EB5D80f94
[14:27:21.061] Testnet address 0xdC7B8A96e0Ce131E1C0562BB0Cf35F12a0D1b6d6: Transactions fetched for 0xdC7B8A96e0Ce131E1C0562BB0Cf35F12a0D1b6d6
[14:27:21.061] Testnet address 0x891F52b828C7242dC95D38903D387D7d12e33CB2: Transactions fetched for 0x891F52b828C7242dC95D38903D387D7d12e33CB2
[14:27:21.061] Mainnet address 0x5D5c5c1d14FaF8Ff704295b2F502dAA9D06799a0: Transactions fetched for 0x5D5c5c1d14FaF8Ff704295b2F502dAA9D06799a0
[14:27:21.061] Mainnet address 0xbe2D8AC2A370972C4328BED520b224C3903A4941: Transactions fetched for 0xbe2D8AC2A370972C4328BED520b224C3903A4941
[14:27:21.061] Mainnet address 0x55b6d96126879Fe99ca1f57A05F81941d0932F9C: Transactions fetched for 0x55b6d96126879Fe99ca1f57A05F81941d0932F9C
[14:27:21.061] Mainnet address 0xF9f594D86AEF52644473edC43B6dC9656E4fD2Ce: Transactions fetched for 0xF9f594D86AEF52644473edC43B6dC9656E4fD2Ce
[14:27:21.061]
[14:27:21.062] ✓ Generating static pages (16/16)
[14:27:21.149] Finalizing page optimization ...
[14:27:21.149] Collecting build traces ...
[14:27:21.154]
When I run the cron job from Settings > Cron Jobs > Run
or via Postman, the runtime logs only show this:
Jul 29 14:36:10.16 GET--- tokens-ui.vercel.app/api/cron-jobs Authorization successful
Jul 29 14:36:10.11 GET200 tokens-ui.vercel.app/api/cron-jobs [GET] [middleware: "src/middleware"] /api/cron-jobs status=200
I have run several tests, and it does work correctly by fetching data with the /api/fetch-transaction
endpoint. It fetches the data and caches it, but the /api/fetch-transaction
endpoint requests never show up in the runtime logs.
Here is the response from the cron-job endpoint when called via Postman:
{
"message": "Cron jobs completed successfully: ",
"response": "Cron jobs completed with the following results:
\nTestnet address 0x70aF4c67f16019C13516D814aAf9A6aD74CFd2F4: Transactions fetched for 0x70aF4c67f16019C13516D814aAf9A6aD74CFd2F4
\nTestnet address 0x9eB947Be4de53332022Edbc51528d33EB5D80f94: Transactions fetched for 0x9eB947Be4de53332022Edbc51528d33EB5D80f94
\nTestnet address 0xdC7B8A96e0Ce131E1C0562BB0Cf35F12a0D1b6d6: Transactions fetched for 0xdC7B8A96e0Ce131E1C0562BB0Cf35F12a0D1b6d6
\nTestnet address 0x891F52b828C7242dC95D38903D387D7d12e33CB2: Transactions fetched for 0x891F52b828C7242dC95D38903D387D7d12e33CB2
\nMainnet address 0x5D5c5c1d14FaF8Ff704295b2F502dAA9D06799a0: Transactions fetched for 0x5D5c5c1d14FaF8Ff704295b2F502dAA9D06799a0
\nMainnet address 0xbe2D8AC2A370972C4328BED520b224C3903A4941: Transactions fetched for 0xbe2D8AC2A370972C4328BED520b224C3903A4941
\nMainnet address 0x55b6d96126879Fe99ca1f57A05F81941d0932F9C: Transactions fetched for 0x55b6d96126879Fe99ca1f57A05F81941d0932F9C
\nMainnet address 0xF9f594D86AEF52644473edC43B6dC9656E4fD2Ce: Transactions fetched for 0xF9f594D86AEF52644473edC43B6dC9656E4fD2Ce\n"
}
Is this behavior expected on Hobby Account, or should the internal API calls made by the cron job be logged in the Vercel runtime logs? Typically, I would expect these internal API requests to appear in the logs for better monitoring and debugging. Your guidance on whether this is the intended functionality or if there might be an issue would be greatly appreciated.
Here are the related codes:
/app/api/cron-jobs/route.ts
import { NextResponse } from "next/server";
import { runCronJobs } from "~~/services/cron/cronJobs";
export async function GET() {
console.log("Cron job endpoint called");
try {
const response = await runCronJobs();
if (response) {
console.log("Cron job completed successfully: ", response);
return NextResponse.json({ message: "Cron jobs completed successfully: ", response }, { status: 200 });
} else {
console.log("No response from runCronJobs");
return NextResponse.json({ error: "No response from runCronJobs" }, { status: 500 });
}
} catch (error) {
console.error("Error running cron jobs:", error);
if (error instanceof Error) {
return NextResponse.json({ error: error.message }, { status: 500 });
} else {
return NextResponse.json({ error: "Unknown error" }, { status: 500 });
}
}
}
/services/cron/cronJobs.ts
"use server";
import scaffoldConfig from "~~/scaffold.config";
const cronSecret = process.env.CRON_SECRET;
const vercelByPass = process.env.VERCEL_BYPASS;
const testnetAddresses = scaffoldConfig.testnetContractAddressList || [];
const mainnetAddresses = scaffoldConfig.contractAddressList || [];
const baseUrl = process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : "https://tokens-ui.vercel.app";
async function fetchTransactions(contractAddress: string, testnet: boolean) {
const url = `${baseUrl}/api/fetch-transactions?contractaddress=${contractAddress}&testnet=${testnet}&allTx=true&cleanCache=true`;
console.log(`Fetching transactions from URL: ${url}`);
const headers: Record<string, string> = {
Authorization: `Bearer ${cronSecret}`,
};
if (vercelByPass) {
headers["x-vercel-protection-bypass"] = vercelByPass;
}
const response = await fetch(url, {
method: "GET",
headers,
});
console.log(`Response status: ${response.status}`);
if (!response.ok) {
console.error(`Failed to fetch transactions: ${response.status} ${response.statusText}`);
throw new Error(`Failed to fetch transactions for ${contractAddress}`);
}
console.log(`Transactions fetched for ${contractAddress}`);
return `Transactions fetched for ${contractAddress}`;
}
async function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
export async function runCronJobs() {
console.log("Cron job started");
let resultMessage = "Cron jobs completed with the following results:\n";
await delay(500);
for (const address of testnetAddresses) {
console.log(`Fetching transactions for testnet address: ${address}`);
try {
const message = await fetchTransactions(address, true);
console.log(`Successfully fetched transactions for testnet address: ${address}`);
resultMessage += `Testnet address ${address}: ${message}\n`;
} catch (error) {
if (error instanceof Error) {
console.error(`Error fetching transactions for testnet address ${address}:`, error);
resultMessage += `Testnet address ${address}: ${error.message}\n`;
}
}
await delay(500);
}
for (const address of mainnetAddresses) {
console.log(`Fetching transactions for mainnet address: ${address}`);
try {
const message = await fetchTransactions(address, false);
console.log(`Successfully fetched transactions for mainnet address: ${address}`);
resultMessage += `Mainnet address ${address}: ${message}\n`;
} catch (error) {
if (error instanceof Error) {
console.error(`Error fetching transactions for mainnet address ${address}:`, error);
resultMessage += `Mainnet address ${address}: ${error.message}\n`;
}
}
await delay(500);
}
console.log("Cron job finished");
return resultMessage;
}