@@ -25,6 +25,7 @@ const moment = require("moment-timezone");
2525const ObjectId = mongoose . Types . ObjectId ;
2626const log4js = require ( "log4js" ) ;
2727const logger = log4js . getLogger ( `${ constants . ENVIRONMENT } -- token-util` ) ;
28+ const apiUsageLogger = log4js . getLogger ( "api-usage-logger" ) ;
2829const async = require ( "async" ) ;
2930const { Kafka } = require ( "kafkajs" ) ;
3031const kafka = new Kafka ( {
@@ -415,6 +416,56 @@ const isIPBlacklistedHelper = async (
415416const isIPBlacklisted = ( ...args ) =>
416417 trampoline ( ( ) => isIPBlacklistedHelper ( ...args ) ) ;
417418
419+ //Create async queue for handling API Usage logs
420+ const apiUsageQueue = async . queue ( async ( task , callback ) => {
421+ try {
422+ const {
423+ timestamp,
424+ token,
425+ client_id,
426+ endpoint,
427+ ip_address,
428+ user_agent,
429+ response_code,
430+ latency,
431+ } = task ;
432+
433+ const logPayload = {
434+ timestamp,
435+ token,
436+ client_id,
437+ endpoint,
438+ ip_address,
439+ user_agent,
440+ response_code,
441+ latency,
442+ } ;
443+
444+ logger . info ( JSON . stringify ( logPayload ) ) ; // Log the structured data
445+ callback ( ) ;
446+ } catch ( error ) {
447+ logger . error (
448+ `🐛🐛 API Usage Queue Internal Server Error --- ${ error . message } `
449+ ) ;
450+ }
451+ } , 1 ) ; // Adjust concurrency as needed
452+
453+ const logAPIUsage = async ( logData ) => {
454+ try {
455+ // Asynchronous Logging using a queue (recommended)
456+ apiUsageQueue . push ( logData ) ;
457+ } catch ( error ) {
458+ // Handle logging errors gracefully
459+ logger . error ( `Error logging API usage: ${ error . message } ` ) ; // Ensure 'logger' is defined
460+ }
461+ } ;
462+
463+ const calculateLatency = ( startTime , endTime = process . hrtime . bigint ( ) ) => {
464+ const nanoseconds = Number ( endTime - startTime ) ;
465+ const milliseconds = nanoseconds / 1000000 ;
466+ return milliseconds ;
467+ } ;
468+
418469const token = {
419470 verifyEmail : async ( request , next ) => {
420471 try {
@@ -672,6 +723,7 @@ const token = {
672723 verifyToken : async ( request , next ) => {
673724 try {
674725 logText ( "I have just entered the verifyToken() function" ) ;
726+ const startTime = process . hrtime . bigint ( ) ; // Start measuring latency
675727 const ip =
676728 request . headers [ "x-client-ip" ] ||
677729 request . headers [ "x-client-original-ip" ] ;
@@ -715,6 +767,30 @@ const token = {
715767 clientOriginalIp : ip ,
716768 endpoint : endpoint ? endpoint : "unknown" ,
717769 } ) ;
770+
771+ const endTime = process . hrtime . bigint ( ) ;
772+ const latency = calculateLatency ( startTime , endTime ) ;
773+
774+ await AccessTokenModel ( "airqo" ) . updateOne (
775+ { token } ,
776+ { $set : { last_used_at : new Date ( ) , last_ip_address : ip } }
777+ ) ;
778+ const logPayload = {
779+ timestamp : new Date ( ) . toISOString ( ) ,
780+ token : accessToken . token ,
781+ client_id : accessToken . client_id ,
782+ endpoint,
783+ ip_address : ip ,
784+ user_agent : request . headers [ "user-agent" ] ,
785+ response_code : 200 ,
786+ latency : latency ,
787+ } ;
788+
789+ if ( constants . ENVIRONMENT === "PRODUCTION ENVIRONMENT" ) {
790+ }
791+ await logAPIUsage ( logPayload ) ;
792+ apiUsageLogger . info ( stringify ( logPayload ) ) ; // Log to stdout (for BigQuery)
793+
718794 return createValidTokenResponse ( ) ;
719795 }
720796 }
0 commit comments