@@ -25,6 +25,7 @@ const moment = require("moment-timezone");
25
25
const ObjectId = mongoose . Types . ObjectId ;
26
26
const log4js = require ( "log4js" ) ;
27
27
const logger = log4js . getLogger ( `${ constants . ENVIRONMENT } -- token-util` ) ;
28
+ const apiUsageLogger = log4js . getLogger ( "api-usage-logger" ) ;
28
29
const async = require ( "async" ) ;
29
30
const { Kafka } = require ( "kafkajs" ) ;
30
31
const kafka = new Kafka ( {
@@ -415,6 +416,56 @@ const isIPBlacklistedHelper = async (
415
416
const isIPBlacklisted = ( ...args ) =>
416
417
trampoline ( ( ) => isIPBlacklistedHelper ( ...args ) ) ;
417
418
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
+
418
469
const token = {
419
470
verifyEmail : async ( request , next ) => {
420
471
try {
@@ -672,6 +723,7 @@ const token = {
672
723
verifyToken : async ( request , next ) => {
673
724
try {
674
725
logText ( "I have just entered the verifyToken() function" ) ;
726
+ const startTime = process . hrtime . bigint ( ) ; // Start measuring latency
675
727
const ip =
676
728
request . headers [ "x-client-ip" ] ||
677
729
request . headers [ "x-client-original-ip" ] ;
@@ -715,6 +767,30 @@ const token = {
715
767
clientOriginalIp : ip ,
716
768
endpoint : endpoint ? endpoint : "unknown" ,
717
769
} ) ;
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
+
718
794
return createValidTokenResponse ( ) ;
719
795
}
720
796
}
0 commit comments