cancel
Showing results for 
Search instead for 
Did you mean: 

Can i write to a file from Traffic script

SOLVED
davec_bourne
New Contributor

Can i write to a file from Traffic script


I am investigating blocking certain countries from visiting our websites but would like to be able to write a count of each country that visits my site out to a file first for analysis. Is this possible within traffic script?

1 ACCEPTED SOLUTION

Accepted Solutions
markbod
Contributor

Re: Can i write to a file from Traffic script

Hi David,

Blocking countries is relatively simple using the geo.* functions in TrafficScript along with connection.close() or http.SendResponse(), but counting the countries first and writing them to file is a little more complicated.

You can't write to files directly with TrafficScript, but you could create an alert and event under System -> Alerts which writes to a file and then call event.emit() within TrafficScript. However that's not very efficient, and you wouldn't want to call it on every request. So you would probably need some code which stored the data in memory using data.local.set(), and then fired off an event.emit() or even a log.info() once an hour.

This example uses log.info() to write the stats to the standard event log once per hour. The stats are recorded using the per process memory store so you will get a count for each Stingray child process (ie one per cpu core in your machine), and you'll need to be running Stingray version 9.4.


sub flushCodes() {


   $codes = data.local.get("CountryCount-Codes");


   foreach ($cc in string.split($codes)) {


      $count = data.local.get("CountryCount-" . $cc );


      $log .= $cc . ":" . $count . " ";


   }


   data.local.reset("CountryCount-");


   data.local.set("CountryCount-lastFlush", sys.time() );


   log.info("CountryLog " . $log);


}



$cc = geo.getCountryCode( request.getRemoteIP() );


if ( ! $cc ) {


   $cc = "UNKNOWN";


}


$count = data.local.get("CountryCount-" . $cc);


if ( ! $count ) {


   $codes = data.local.get("CountryCount-Codes");


   if ( ! $codes ) {


      $codes = $cc;


   } else {


      $codes .= " " . $cc;


   }


   data.local.set("CountryCount-Codes", $codes);


   $count = 0;


}


data.local.set("CountryCount-" . $cc, ++$count);



$flush = data.local.get("CountryCount-lastFlush");


if ( ! $flush ) {


   data.local.set("CountryCount-lastFlush", sys.time() );


} else {


   if ( sys.time() - $flush > 3600 ) {


      flushCodes();


   }


}


Alternatively you could use the Request Logging feature of the Virtual Server, and record the country code from a TrafficScript variable. Then post-process the log to count the incidence of countries later.

Cheers,

Mark

View solution in original post

3 REPLIES 3
markbod
Contributor

Re: Can i write to a file from Traffic script

Hi David,

Blocking countries is relatively simple using the geo.* functions in TrafficScript along with connection.close() or http.SendResponse(), but counting the countries first and writing them to file is a little more complicated.

You can't write to files directly with TrafficScript, but you could create an alert and event under System -> Alerts which writes to a file and then call event.emit() within TrafficScript. However that's not very efficient, and you wouldn't want to call it on every request. So you would probably need some code which stored the data in memory using data.local.set(), and then fired off an event.emit() or even a log.info() once an hour.

This example uses log.info() to write the stats to the standard event log once per hour. The stats are recorded using the per process memory store so you will get a count for each Stingray child process (ie one per cpu core in your machine), and you'll need to be running Stingray version 9.4.


sub flushCodes() {


   $codes = data.local.get("CountryCount-Codes");


   foreach ($cc in string.split($codes)) {


      $count = data.local.get("CountryCount-" . $cc );


      $log .= $cc . ":" . $count . " ";


   }


   data.local.reset("CountryCount-");


   data.local.set("CountryCount-lastFlush", sys.time() );


   log.info("CountryLog " . $log);


}



$cc = geo.getCountryCode( request.getRemoteIP() );


if ( ! $cc ) {


   $cc = "UNKNOWN";


}


$count = data.local.get("CountryCount-" . $cc);


if ( ! $count ) {


   $codes = data.local.get("CountryCount-Codes");


   if ( ! $codes ) {


      $codes = $cc;


   } else {


      $codes .= " " . $cc;


   }


   data.local.set("CountryCount-Codes", $codes);


   $count = 0;


}


data.local.set("CountryCount-" . $cc, ++$count);



$flush = data.local.get("CountryCount-lastFlush");


if ( ! $flush ) {


   data.local.set("CountryCount-lastFlush", sys.time() );


} else {


   if ( sys.time() - $flush > 3600 ) {


      flushCodes();


   }


}


Alternatively you could use the Request Logging feature of the Virtual Server, and record the country code from a TrafficScript variable. Then post-process the log to count the incidence of countries later.

Cheers,

Mark

davec_bourne
New Contributor

Re: Can i write to a file from Traffic script

Thanks mark, That looks perfect.

owen
Frequent Contributor

Re: Can i write to a file from Traffic script

Mark Boddington's solution is a great approach.

Just for completeness, here's a few alternatives that illustrate how to: