diff --git a/agc_2-X/trunk/UPGRADE b/agc_2-X/trunk/UPGRADE index 7f077208..718b6d23 100644 --- a/agc_2-X/trunk/UPGRADE +++ b/agc_2-X/trunk/UPGRADE @@ -82,6 +82,8 @@ OTHER CHANGES: 9. Added api_only_user User option to prevent access to admin and agent screens by an API-only user account. +10. Added logging of API request URLs + diff --git a/agc_2-X/trunk/bin/ADMIN_archive_log_tables.pl b/agc_2-X/trunk/bin/ADMIN_archive_log_tables.pl index 3c9041c4..08b9e089 100644 --- a/agc_2-X/trunk/bin/ADMIN_archive_log_tables.pl +++ b/agc_2-X/trunk/bin/ADMIN_archive_log_tables.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl # -# ADMIN_archive_log_tables.pl version 2.12 +# ADMIN_archive_log_tables.pl version 2.14 # # This script is designed to put all records from call_log, vicidial_log and # vicidial_agent_log in relevant _archive tables and delete records in original @@ -20,7 +20,7 @@ # Based on perl scripts in ViciDial from Matt Florell and post: # http://www.vicidial.org/VICIDIALforum/viewtopic.php?p=22506&sid=ca5347cffa6f6382f56ce3db9fb3d068#22506 # -# Copyright (C) 2016 I. Taushanov, Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2017 I. Taushanov, Matt Florell LICENSE: AGPLv2 # # CHANGES # 90615-1701 - First version @@ -45,6 +45,7 @@ # 160612-0703 - Added --only-trim-archive-... options # 160827-0957 - Added --recording-log-days=X option # 161212-1659 - Added --cpd-log-purge-days=XX option +# 170209-1213 - Added vicidial_api_urls table rolling and purging to all vicidial_api_log sections # $CALC_TEST=0; @@ -495,6 +496,33 @@ if (!$T) $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; } + + $stmtA = "SELECT count(*) from vicidial_api_urls_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $vicidial_api_urls_archive_count = $aryA[0]; + } + $sthA->finish(); + + if (!$Q) {print "Trimming vicidial_api_urls_archive table... ($vicidial_api_urls_archive_count)\n";} + + $rv = $sthA->err(); + if (!$rv) + { + $stmtA = "DELETE FROM vicidial_api_urls_archive WHERE api_date < '$del_time';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows deleted from vicidial_api_urls_archive table \n";} + + $stmtA = "optimize table vicidial_api_urls_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + } ##### END vicidial_api_log_archive trim processing ##### } @@ -796,6 +824,57 @@ if (!$T) ##### END vicidial_api_log DAILY processing ##### + ##### BEGIN vicidial_api_urls DAILY processing ##### + $stmtA = "SELECT count(*) from vicidial_api_urls;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $vicidial_api_urls_count = $aryA[0]; + } + $sthA->finish(); + + $stmtA = "SELECT count(*) from vicidial_api_urls_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $vicidial_api_urls_archive_count = $aryA[0]; + } + $sthA->finish(); + + if (!$Q) {print "\nProcessing vicidial_api_urls table... ($vicidial_api_urls_count|$vicidial_api_urls_archive_count)\n";} + $stmtA = "INSERT IGNORE INTO vicidial_api_urls_archive SELECT * from vicidial_api_urls;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows inserted into vicidial_api_urls_archive table \n";} + + $rv = $sthA->err(); + if (!$rv) + { + $stmtA = "DELETE FROM vicidial_api_urls WHERE api_date < '$del_time';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows deleted from vicidial_api_urls table \n";} + + $stmtA = "optimize table vicidial_api_urls;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $stmtA = "optimize table vicidial_api_urls_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + } + ##### END vicidial_api_urls DAILY processing ##### + + if ($carrier_daily) { ##### BEGIN vicidial_carrier_log DAILY processing ##### @@ -1299,6 +1378,56 @@ if (!$T) } + ##### vicidial_api_urls + $stmtA = "SELECT count(*) from vicidial_api_urls;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $vicidial_api_urls_count = $aryA[0]; + } + $sthA->finish(); + + $stmtA = "SELECT count(*) from vicidial_api_urls_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $vicidial_api_urls_archive_count = $aryA[0]; + } + $sthA->finish(); + + if (!$Q) {print "\nProcessing vicidial_api_urls table... ($vicidial_api_urls_count|$vicidial_api_urls_archive_count)\n";} + $stmtA = "INSERT IGNORE INTO vicidial_api_urls_archive SELECT * from vicidial_api_urls;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows inserted into vicidial_api_urls_archive table \n";} + + $rv = $sthA->err(); + if (!$rv) + { + $stmtA = "DELETE FROM vicidial_api_urls WHERE api_date < '$del_time';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows deleted from vicidial_api_urls table \n";} + + $stmtA = "optimize table vicidial_api_urls;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $stmtA = "optimize table vicidial_api_urls_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + } + + ##### vicidial_log_noanswer $stmtA = "SELECT count(*) from vicidial_log_noanswer;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; diff --git a/agc_2-X/trunk/docs/AGENT_API.txt b/agc_2-X/trunk/docs/AGENT_API.txt index 80a2a6d4..e75cd40d 100644 --- a/agc_2-X/trunk/docs/AGENT_API.txt +++ b/agc_2-X/trunk/docs/AGENT_API.txt @@ -1,4 +1,4 @@ -AGENT API DOCUMENT Started: 2008-07-03 Updated: 2015-04-29 +AGENT API DOCUMENT Started: 2008-07-03 Updated: 2017-02-09 This document describes the functions of an API(Application Programming Interface) for the VICIDIAL Agent screen. This functionality will be rather limited at first diff --git a/agc_2-X/trunk/docs/NON-AGENT_API.txt b/agc_2-X/trunk/docs/NON-AGENT_API.txt index 0f5c67ee..95057e02 100644 --- a/agc_2-X/trunk/docs/NON-AGENT_API.txt +++ b/agc_2-X/trunk/docs/NON-AGENT_API.txt @@ -1,4 +1,4 @@ -NON-AGENT API DOCUMENT Started: 2008-07-24 Updated: 2017-02-04 +NON-AGENT API DOCUMENT Started: 2008-07-24 Updated: 2017-02-09 This document describes the functions of an API(Application Programming Interface) for all functions NOT directly relating to the VICIDIAL Agent screen. @@ -117,6 +117,7 @@ Changes: 160709-2219 - Added lead_field_info function 161020-1042 - Added lookup_state option to add_lead, added 10-digit validation if usacan_areacode_check enabled 170204-0947 - Added phone_number_log function +170209-1149 - Added URL and IP logging API Functions use the 'function' variable diff --git a/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql b/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql index c50b29df..ead64f8d 100644 --- a/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql +++ b/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql @@ -3591,6 +3591,13 @@ index (channel_group), index (park_end_time) ) ENGINE=MyISAM; +CREATE TABLE vicidial_api_urls ( +api_id INT(9) UNSIGNED PRIMARY KEY NOT NULL, +api_date DATETIME, +remote_ip VARCHAR(50), +url MEDIUMTEXT +) ENGINE=MyISAM; + ALTER TABLE vicidial_email_list MODIFY message text character set utf8; @@ -3766,6 +3773,7 @@ CREATE UNIQUE INDEX vddla on vicidial_dial_log_archive (caller_code,call_date); CREATE TABLE vicidial_api_log_archive LIKE vicidial_api_log; ALTER TABLE vicidial_api_log_archive MODIFY api_id INT(9) UNSIGNED NOT NULL; +CREATE TABLE vicidial_api_urls_archive LIKE vicidial_api_urls; CREATE TABLE vicidial_callbacks_archive LIKE vicidial_callbacks; ALTER TABLE vicidial_callbacks_archive MODIFY callback_id INT(9) UNSIGNED NOT NULL; @@ -3848,4 +3856,4 @@ UPDATE vicidial_configuration set value='1766' where name='qc_database_version'; UPDATE system_settings set vdc_agent_api_active='1'; -UPDATE system_settings SET db_schema_version='1486',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1487',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/agc_2-X/trunk/extras/upgrade_2.14.sql b/agc_2-X/trunk/extras/upgrade_2.14.sql index 8c2543e8..2cfbc000 100644 --- a/agc_2-X/trunk/extras/upgrade_2.14.sql +++ b/agc_2-X/trunk/extras/upgrade_2.14.sql @@ -38,3 +38,14 @@ UPDATE system_settings SET db_schema_version='1485',db_schema_update_date=NOW() ALTER TABLE vicidial_users ADD api_only_user ENUM('0','1') default '0'; UPDATE system_settings SET db_schema_version='1486',db_schema_update_date=NOW() where db_schema_version < 1486; + +CREATE TABLE vicidial_api_urls ( +api_id INT(9) UNSIGNED PRIMARY KEY NOT NULL, +api_date DATETIME, +remote_ip VARCHAR(50), +url MEDIUMTEXT +) ENGINE=MyISAM; + +CREATE TABLE vicidial_api_urls_archive LIKE vicidial_api_urls; + +UPDATE system_settings SET db_schema_version='1487',db_schema_update_date=NOW() where db_schema_version < 1487; diff --git a/agc_2-X/trunk/www/agc/api.php b/agc_2-X/trunk/www/agc/api.php index 8fae48d4..613fa398 100644 --- a/agc_2-X/trunk/www/agc/api.php +++ b/agc_2-X/trunk/www/agc/api.php @@ -1,7 +1,7 @@ LICENSE: AGPLv2 +# Copyright (C) 2017 Matt Florell LICENSE: AGPLv2 # # This script is designed as an API(Application Programming Interface) to allow # other programs to interact with the VICIDIAL Agent screen @@ -87,17 +87,29 @@ # 160113-0921 - Fix for numeric audio files in playback function # 161102-1042 - Fixed QM partition problem # 161103-1729 - Added agent_debug to audio playing +# 170209-1222 - Added URL and IP logging # -$version = '2.12-53'; -$build = '161103-1729'; +$version = '2.14-54'; +$build = '170209-1222'; $startMS = microtime(); require_once("dbconnect_mysqli.php"); require_once("functions.php"); +$ip = getenv("REMOTE_ADDR"); $query_string = getenv("QUERY_STRING"); +$REQUEST_URI = getenv("REQUEST_URI"); +$POST_URI = ''; +foreach($_POST as $key=>$value) + {$POST_URI .= '&'.$key.'='.$value;} +if (strlen($POST_URI)>1) + {$POST_URI = preg_replace("/^&/",'',$POST_URI);} +$REQUEST_URI = preg_replace("/'|\"|\\\\|;/","",$REQUEST_URI); +$POST_URI = preg_replace("/'|\"|\\\\|;/","",$POST_URI); +if ( (strlen($query_string) < 3) and (strlen($POST_URI) > 2) ) + {$query_string = $POST_URI;} ### If you have globals turned off uncomment these lines if (isset($_GET["user"])) {$user=$_GET["user"];} @@ -3900,7 +3912,7 @@ function api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$val { if ($api_logging > 0) { - global $startMS; + global $startMS, $query_string, $ip; $CL=':'; $script_name = getenv("SCRIPT_NAME"); @@ -3911,6 +3923,7 @@ function api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$val if (($server_port == '80') or ($server_port == '443') ) {$server_port='';} else {$server_port = "$CL$server_port";} $apiPAGE = "$HTTPprotocol$server_name$server_port$script_name"; + $apiURL = $apiPAGE . '?' . $query_string; $endMS = microtime(); $startMSary = explode(" ",$startMS); @@ -3965,6 +3978,14 @@ function api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$val $NOW_TIME = date("Y-m-d H:i:s"); $stmt="INSERT INTO vicidial_api_log set user='$user',agent_user='$agent_user',function='$function',value='$value',result='$result',result_reason='$result_reason',source='$source',data='$data',api_date='$NOW_TIME',api_script='$api_script',run_time='$TOTALrun',webserver='$webserver_id',api_url='$url_id';"; $rslt=mysql_to_mysqli($stmt, $link); + $ALaffected_rows = mysqli_affected_rows($link); + $api_id = mysqli_insert_id($link); + + if ($ALaffected_rows > 0) + { + $stmt="INSERT INTO vicidial_api_urls set api_id='$api_id',api_date=NOW(),remote_ip='$ip',url='$apiURL';"; + $rslt=mysql_to_mysqli($stmt, $link); + } } return 1; } diff --git a/agc_2-X/trunk/www/vicidial/AST_API_log_report.php b/agc_2-X/trunk/www/vicidial/AST_API_log_report.php index 7c593803..2f1b4d88 100644 --- a/agc_2-X/trunk/www/vicidial/AST_API_log_report.php +++ b/agc_2-X/trunk/www/vicidial/AST_API_log_report.php @@ -3,11 +3,12 @@ # # This report is for viewing the a report of API activity to the vicidial_api_log table # -# Copyright (C) 2016 Joe Johnson, Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2017 Joe Johnson, Matt Florell LICENSE: AGPLv2 # # CHANGES # # 160305-0842 - First build +# 170209-1237 - Added URL and IP display # $startMS = microtime(); @@ -45,6 +46,8 @@ if (isset($_GET["report_display_type"])) {$report_display_type=$_GET["report_d elseif (isset($_POST["report_display_type"])) {$report_display_type=$_POST["report_display_type"];} if (isset($_GET["search_archived_data"])) {$search_archived_data=$_GET["search_archived_data"];} elseif (isset($_POST["search_archived_data"])) {$search_archived_data=$_POST["search_archived_data"];} +if (isset($_GET["show_urls"])) {$show_urls=$_GET["show_urls"];} + elseif (isset($_POST["show_urls"])) {$show_urls=$_POST["show_urls"];} if (isset($_GET["DB"])) {$DB=$_GET["DB"];} elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];} @@ -100,10 +103,12 @@ for ($t=0; $t 0) { $row=mysqli_fetch_row($rslt); $VUselected_language = $row[0]; + $VUmodify_same_user_level = $row[1]; + $VUuser_level = $row[2]; + $VUmodify_users = $row[3]; } $auth=0; @@ -472,7 +480,7 @@ while ($row=mysqli_fetch_array($rslt)) { if ($DB) {echo "$user_group_string|$user_group_ct|$user_groupQS|$i
\n";} -$LINKbase = "$PHP_SELF?DB=$DB&api_date_D=$api_date_D&api_date_T=$api_date_T&api_date_end_D=$api_date_end_D&api_date_end_T=$api_date_end_T$resultQS$functionQS$agent_userQS$userQS&shift=$shift&DB=$DB&show_percentages=$show_percentages&SUBMIT=1"; +$LINKbase = "$PHP_SELF?DB=$DB&api_date_D=$api_date_D&api_date_T=$api_date_T&api_date_end_D=$api_date_end_D&api_date_end_T=$api_date_end_T$resultQS$functionQS$agent_userQS$userQS&shift=$shift&DB=$DB&show_percentages=$show_percentages&show_urls=$show_urls&search_archived_data=$search_archived_data&SUBMIT=1"; $NWB = "   \"HELP\""; @@ -604,10 +612,12 @@ $HTML_text.="\n"; $HTML_text.="

"; $HTML_text.="\n"; +$HTML_text.="

"._QXZ("Show URLs, slower")."\n"; if ($archives_available=="Y") { - $HTML_text.="

"._QXZ("Search archived data")."\n"; + $HTML_text.="
"._QXZ("Search archived data")."\n"; } + $HTML_text.=""; $HTML_text.=""; $HTML_text.="\n\n"; @@ -616,20 +626,37 @@ $HTML_text.="
\n";
 
 if ($SUBMIT && $api_date_D && $api_date_T && $api_date_end_D && $api_date_end_T) 
 	{
-	$stmt="select * from $vicidial_api_log_table where api_date>='$api_date_D $api_date_T' and api_date<='$api_date_end_D $api_date_end_T' $result_SQL $function_SQL $agent_user_SQL $user_SQL order by $order_by asc";
+	$stmt="select api_id,user,api_date,api_script,function,agent_user,value,result,result_reason,source,data,run_time,webserver,api_url from $vicidial_api_log_table where api_date>='$api_date_D $api_date_T' and api_date<='$api_date_end_D $api_date_end_T' $result_SQL $function_SQL $agent_user_SQL $user_SQL order by $order_by asc";
+	if ($show_urls)
+		{
+		$stmt="select A.api_id,user,A.api_date,api_script,function,agent_user,value,result,result_reason,source,data,run_time,webserver,api_url,remote_ip,url from $vicidial_api_log_table A, $vicidial_api_urls_table B where A.api_date>='$api_date_D $api_date_T' and A.api_date<='$api_date_end_D $api_date_end_T' and A.api_id=B.api_id $result_SQL $function_SQL $agent_user_SQL $user_SQL order by $order_by asc";
+		}
 	if ($DB) {print $stmt."\n";}
 	# print $stmt."\n";
 
+	$URL_header='';
 	$ASCII_border="+---------------------+--------------------------------+------------+----------------------+--------------------------------+------------+----------------------+----------+-----------+-----------+\n";
+	if ($show_urls)
+		{
+		$ASCII_border="+---------------------+--------------------------------+------------+----------------------+--------------------------------+------------+----------------------+----------+-----------+-----------+----------------------+----------\n";
+		$URL_header="  REMOTE IP           |    URL";
+		}
 	$HTML_text.=$ASCII_rpt_header;
 	$HTML_text.=sprintf("%110s", " ");
-	$HTML_text.=""._QXZ("DOWNLOAD")."\n";
+	$HTML_text.=""._QXZ("DOWNLOAD")."\n";
 
 	$HTML_text.=$ASCII_border;
-	$HTML_text.="| API DATE            | USER                           | API SCRIPT | FUNCTION             | AGENT USER                     | RESULT     | SOURCE               | RUN TIME | WEBSERVER | API URL   |\n";
+	$HTML_text.="| API DATE            | USER                           | API SCRIPT | FUNCTION             | AGENT USER                     | RESULT     | SOURCE               | RUN TIME | WEBSERVER | API URL   |$URL_header\n";
 	$HTML_text.=$ASCII_border;
 
-	$CSV_text.="\n\"API DATE\",\"USER\",\"API SCRIPT\",\"FUNCTION\",\"AGENT USER\",\"VALUE\",\"RESULT\",\"RESULT REASON\",\"SOURCE\",\"DATA\",\"RUN TIME\",\"WEBSERVER\",\"API URL\"\n";
+	if ($show_urls)
+		{
+		$CSV_text.="\n\"API DATE\",\"USER\",\"API SCRIPT\",\"FUNCTION\",\"AGENT USER\",\"VALUE\",\"RESULT\",\"RESULT REASON\",\"SOURCE\",\"DATA\",\"RUN TIME\",\"WEBSERVER\",\"API URL\",\"REMOTE IP\",\"FULL URL STRING\"\n";
+		}
+	else
+		{
+		$CSV_text.="\n\"API DATE\",\"USER\",\"API SCRIPT\",\"FUNCTION\",\"AGENT USER\",\"VALUE\",\"RESULT\",\"RESULT REASON\",\"SOURCE\",\"DATA\",\"RUN TIME\",\"WEBSERVER\",\"API URL\"\n";
+		}
 
 	$rslt=mysql_to_mysqli($stmt, $link);
 	while ($row=mysqli_fetch_array($rslt)) 
@@ -646,8 +673,21 @@ if ($SUBMIT && $api_date_D && $api_date_T && $api_date_end_D && $api_date_end_T)
 		$HTML_text.=sprintf("%-20s", $row["source"])." | ";
 		$HTML_text.=sprintf("%-8s", substr($row["run_time"],0,8))." | ";
 		$HTML_text.=sprintf("%-9s", $row["webserver"])." | ";
-		$HTML_text.=sprintf("%-9s", $row["api_url"])." |\n";
-		$CSV_text.="\"$row[api_date]\",\"$full_user\",\"$row[api_script]\",\"$row[function]\",\"$full_agent_user\",\"$row[value]\",\"$row[result]\",\"$row[result_reason]\",\"$row[source]\",\"$row[data]\",\"$row[run_time]\",\"$row[webserver]\",\"$row[api_url]\"\n";
+		$HTML_text.=sprintf("%-9s", $row["api_url"])." | ";
+		if ($show_urls)
+			{
+			$full_url = $row["url"];
+			if ( ($VUmodify_same_user_level < 1) or ($VUuser_level < 9) or ($VUmodify_users < 1) )
+				{$full_url = preg_replace("/&pass=[\s\S]+?&/",'&pass=XXXX&',$full_url);}
+			$HTML_text.=sprintf("%-20s", $row["remote_ip"])." | ";
+			$HTML_text.=sprintf("%-2000s", $full_url)." | ";
+			$CSV_text.="\"$row[api_date]\",\"$full_user\",\"$row[api_script]\",\"$row[function]\",\"$full_agent_user\",\"$row[value]\",\"$row[result]\",\"$row[result_reason]\",\"$row[source]\",\"$row[data]\",\"$row[run_time]\",\"$row[webserver]\",\"$row[api_url]\",\"$row[remote_ip]\",\"$full_url\"\n";
+			}
+		else
+			{
+			$CSV_text.="\"$row[api_date]\",\"$full_user\",\"$row[api_script]\",\"$row[function]\",\"$full_agent_user\",\"$row[value]\",\"$row[result]\",\"$row[result_reason]\",\"$row[source]\",\"$row[data]\",\"$row[run_time]\",\"$row[webserver]\",\"$row[api_url]\"\n";
+			}
+		$HTML_text.="\n";
 		}
 	$HTML_text.=$ASCII_border;
 	}
diff --git a/agc_2-X/trunk/www/vicidial/non_agent_api.php b/agc_2-X/trunk/www/vicidial/non_agent_api.php
index 924cd2ce..25cc0c80 100644
--- a/agc_2-X/trunk/www/vicidial/non_agent_api.php
+++ b/agc_2-X/trunk/www/vicidial/non_agent_api.php
@@ -111,10 +111,11 @@
 # 160824-0802 - Fixed issue with allowed lists feature
 # 161020-1042 - Added lookup_state option to add_lead, added 10-digit validation if usacan_areacode_check enabled
 # 170205-2022 - Added phone_number_log function
+# 170209-1149 - Added URL and IP logging
 #
 
-$version = '2.14-87';
-$build = '170205-2022';
+$version = '2.14-88';
+$build = '170209-1149';
 $api_url_log = 0;
 
 $startMS = microtime();
@@ -613,6 +614,18 @@ $NOW_TIME = date("Y-m-d H:i:s");
 $CIDdate = date("mdHis");
 $ENTRYdate = date("YmdHis");
 $ip = getenv("REMOTE_ADDR");
+$query_string = getenv("QUERY_STRING");
+$REQUEST_URI = getenv("REQUEST_URI");
+$POST_URI = '';
+foreach($_POST as $key=>$value)
+	{$POST_URI .= '&'.$key.'='.$value;}
+if (strlen($POST_URI)>1)
+	{$POST_URI = preg_replace("/^&/",'',$POST_URI);}
+$REQUEST_URI = preg_replace("/'|\"|\\\\|;/","",$REQUEST_URI);
+$POST_URI = preg_replace("/'|\"|\\\\|;/","",$POST_URI);
+if ( (strlen($query_string) < 3) and (strlen($POST_URI) > 2) )
+	{$query_string = $POST_URI;}
+
 $MT[0]='';
 $api_script = 'non-agent';
 $api_logging = 1;
@@ -9900,7 +9913,7 @@ function api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$val
 	{
 	if ($api_logging > 0)
 		{
-		global $startMS;
+		global $startMS, $query_string, $ip;
 
 		$CL=':';
 		$script_name = getenv("SCRIPT_NAME");
@@ -9911,6 +9924,7 @@ function api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$val
 		if (($server_port == '80') or ($server_port == '443') ) {$server_port='';}
 		else {$server_port = "$CL$server_port";}
 		$apiPAGE = "$HTTPprotocol$server_name$server_port$script_name";
+		$apiURL = $apiPAGE . '?' . $query_string;
 
 		$endMS = microtime();
 		$startMSary = explode(" ",$startMS);
@@ -9965,6 +9979,14 @@ function api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$val
 		$NOW_TIME = date("Y-m-d H:i:s");
 		$stmt="INSERT INTO vicidial_api_log set user='$user',agent_user='$agent_user',function='$function',value='$value',result='$result',result_reason='$result_reason',source='$source',data='$data',api_date='$NOW_TIME',api_script='$api_script',run_time='$TOTALrun',webserver='$webserver_id',api_url='$url_id';";
 		$rslt=mysql_to_mysqli($stmt, $link);
+		$ALaffected_rows = mysqli_affected_rows($link);
+		$api_id = mysqli_insert_id($link);
+
+		if ($ALaffected_rows > 0)
+			{
+			$stmt="INSERT INTO vicidial_api_urls set api_id='$api_id',api_date=NOW(),remote_ip='$ip',url='$apiURL';";
+			$rslt=mysql_to_mysqli($stmt, $link);
+			}
 		}
 	return 1;
 	}