How to create a logfile in php - php

I want to create a logfile for my system to register/log every action they do inside the system. But I have no idea how to do it.
For example, I have this php code that does the login function.
public function hasAccess($username,$password){
$form = array();
$form['username'] = $username;
$form['password'] = $password;
$securityDAO = $this->getDAO('SecurityDAO');
$result = $securityDAO->hasAccess($form);
//var_dump($form);
//var_dump($result);
if($result[0]['success']=='1'){
$this->Session->add('user_id', $result[0]['id']);
//$this->Session->add('username', $result[0]['username']);
//$this->Session->add('roleid', $result[0]['roleid']);
return $this->status(0,true,'auth.success',$result);
}else{
return $this->status(0,false,'auth.failed',$result);
}
}
now I want to create a logfile entitled 'the date today', then when that functions is used for loging in, it will write that user has logged in, the same with other functions. But I only want a single file for every day.
Could anyone be kind enough to guide and teach me how I should do my code?

To write to a log file and make a new one each day, you could use date("j.n.Y") as part of the filename.
//Something to write to txt log
$log = "User: ".$_SERVER['REMOTE_ADDR'].' - '.date("F j, Y, g:i a").PHP_EOL.
"Attempt: ".($result[0]['success']=='1'?'Success':'Failed').PHP_EOL.
"User: ".$username.PHP_EOL.
"-------------------------".PHP_EOL;
//Save string to log, use FILE_APPEND to append.
file_put_contents('./log_'.date("j.n.Y").'.log', $log, FILE_APPEND);
So you would place that within your hasAccess() method.
public function hasAccess($username,$password){
$form = array();
$form['username'] = $username;
$form['password'] = $password;
$securityDAO = $this->getDAO('SecurityDAO');
$result = $securityDAO->hasAccess($form);
//Write action to txt log
$log = "User: ".$_SERVER['REMOTE_ADDR'].' - '.date("F j, Y, g:i a").PHP_EOL.
"Attempt: ".($result[0]['success']=='1'?'Success':'Failed').PHP_EOL.
"User: ".$username.PHP_EOL.
"-------------------------".PHP_EOL;
//-
file_put_contents('./log_'.date("j.n.Y").'.txt', $log, FILE_APPEND);
if($result[0]['success']=='1'){
$this->Session->add('user_id', $result[0]['id']);
//$this->Session->add('username', $result[0]['username']);
//$this->Session->add('roleid', $result[0]['roleid']);
return $this->status(0,true,'auth.success',$result);
}else{
return $this->status(0,false,'auth.failed',$result);
}
}

create a logfile in php, to do it you need to pass data on function and it will create log file for you.
function wh_log($log_msg)
{
$log_filename = "log";
if (!file_exists($log_filename))
{
// create directory/folder uploads.
mkdir($log_filename, 0777, true);
}
$log_file_data = $log_filename.'/log_' . date('d-M-Y') . '.log';
// if you don't add `FILE_APPEND`, the file will be erased each time you add a log
file_put_contents($log_file_data, $log_msg . "\n", FILE_APPEND);
}
// call to function
wh_log("this is my log message");

Agree with the #jon answer. Just added modified the path to create the log directory inside the root
function wh_log($log_msg) {
$log_filename = $_SERVER['DOCUMENT_ROOT']."/log";
if (!file_exists($log_filename))
{
// create directory/folder uploads.
mkdir($log_filename, 0777, true);
}
$log_file_data = $log_filename.'/log_' . date('d-M-Y') . '.log';
file_put_contents($log_file_data, $log_msg . "\n", FILE_APPEND);
}
wh_log('log to file');
just added $_SERVER['DOCUMENT_ROOT']

Please check with this documentation.
http://php.net/manual/en/function.error-log.php
Example:
<?php
// Send notification through the server log if we can not
// connect to the database.
if (!Ora_Logon($username, $password)) {
error_log("Oracle database not available!", 0);
}
// Notify administrator by email if we run out of FOO
if (!($foo = allocate_new_foo())) {
error_log("Big trouble, we're all out of FOOs!", 1,
"operator#example.com");
}
// another way to call error_log():
error_log("You messed up!", 3, "/var/tmp/my-errors.log");
?>

Please check this code, it works fine for me.
$data = array('shopid'=>3,'version'=> 1,'value=>1'); //here $data is dummy varaible
error_log(print_r($data,true), 3, $_SERVER['DOCUMENT_ROOT']."/your-file-name.log");
//In $data we can mention the error messege and create the log

You could use built-in function trigger_error() to trigger user errors/warnings/notices and set_error_handler() to handle them. Inside your error handler you might want to use error_log() or file_put_contents() to store all records on files. To have a single file for every day just use something like sprintf('%s.log', date('Y-m-d')) as filename. And now you should know where to start... :)

This is my working code. Thanks to Paulo for the links. You create a custom error handler and call the trigger_error function with the correct $errno exception, even if it's not an error. Make sure you can write to the log file directory without administrator access.
<?php
$logfile_dir = "C:\workspace\logs\\"; // or "/var/log/" for Linux
$logfile = $logfile_dir . "php_" . date("y-m-d") . ".log";
$logfile_delete_days = 30;
function error_handler($errno, $errstr, $errfile, $errline)
{
global $logfile_dir, $logfile, $logfile_delete_days;
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting, so let it fall
// through to the standard PHP error handler
return false;
}
$filename = basename($errfile);
switch ($errno) {
case E_USER_ERROR:
file_put_contents($logfile, date("y-m-d H:i:s.").gettimeofday()["usec"] . " $filename ($errline): " . "ERROR >> message = [$errno] $errstr\n", FILE_APPEND | LOCK_EX);
exit(1);
break;
case E_USER_WARNING:
file_put_contents($logfile, date("y-m-d H:i:s.").gettimeofday()["usec"] . " $filename ($errline): " . "WARNING >> message = $errstr\n", FILE_APPEND | LOCK_EX);
break;
case E_USER_NOTICE:
file_put_contents($logfile, date("y-m-d H:i:s.").gettimeofday()["usec"] . " $filename ($errline): " . "NOTICE >> message = $errstr\n", FILE_APPEND | LOCK_EX);
break;
default:
file_put_contents($logfile, date("y-m-d H:i:s.").gettimeofday()["usec"] . " $filename ($errline): " . "UNKNOWN >> message = $errstr\n", FILE_APPEND | LOCK_EX);
break;
}
// delete any files older than 30 days
$files = glob($logfile_dir . "*");
$now = time();
foreach ($files as $file)
if (is_file($file))
if ($now - filemtime($file) >= 60 * 60 * 24 * $logfile_delete_days)
unlink($file);
return true; // Don't execute PHP internal error handler
}
set_error_handler("error_handler");
trigger_error("testing 1,2,3", E_USER_NOTICE);
?>

Use below function
// Enable error reporting
ini_set('display_errors', 1);
//Report runtime errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);
//error_reporting(E_ALL & ~E_NOTICE);
// Tell php where your custom php error log is
ini_set('error_log', 'php_error.log');
$dateTime=date("Y-m-d H:i:s");
$ip= $_SERVER['REMOTE_ADDR'];
$errorString="Error occured on time $dateTime by ip $ip";
$php_error_msg.=$errorString;
// Append the error message to the php-error log
//error_log($php_error_msg);
error_log("A custom error has been triggered",1,"email_address","From: email_address");
Above function will create a log in file php_error with proper description and email will be sent.

For printing log use this function, this will create log file in log folder. Create log folder if its not exists .
logger("Your msg in log ", "Filename you want ", "Data to be log string or array or object");
function logger($logMsg="logger", $filename="logger", $logData=""){
$log = date("j.n.Y h:i:s")." || $logMsg : ".print_r($logData,1).PHP_EOL .
"-------------------------".PHP_EOL;
file_put_contents('./log/'.$filename.date("j.n.Y").'.log', $log, FILE_APPEND);
}

A custom log function (for php server):
Features:
logs will be hidden (invisible) to public (without doing setting on server)
easy to read logs data
function log_it($info)
{
$filename = $_SERVER['DOCUMENT_ROOT'] . '/' . '1LOGS.php';
$dieCode = "<?php die();?>";
$fileStart = #file_get_contents($filename, false, null, 0, 14);
if ($fileStart) {
if ($fileStart !== $dieCode)
file_put_contents($filename, $dieCode . file_get_contents($filename));
} else file_put_contents($filename, $dieCode);
if (is_string($info) || is_int($info) || is_float($info)) $txt = ' ' . $info;
elseif (is_array($info) || is_object($info)) $txt = PHP_EOL . ' ' . print_r($info, true);
else $txt = ' ' . 'Data Type: ' . gettype($info);
file_put_contents(
$filename,
PHP_EOL . '>>> ( Date:' . date("Y:m:d H:i:s") . ' )' . $txt,
FILE_APPEND
);
}
inform if it has room for improvement

Here's my PHP log function:
If you want to edit the log rows $maxLogs=5,
or the order to write your logs $logOrder='top'
<?php
##### Start Script
lg('Script start','start');
#Code......
lg('Script end','end');
function lg($str,$mod='Your Log Category'){
$ts = microtime(true);
if(!defined('logTimer')){
define('logTimer',microtime(true));
}
$diff=abs(round(($ts-logTimer)*1000,2));
$maxLogs=5;
$logOrder='top';#new Logs at top
$filename = './log.txt';
$log=[];
if(!file_exists($filename)){
if(!file_put_contents($filename,json_encode($log,128))){
echo "Can’t open to write '$filename' Check Permissions";
return;
}
}else{
$c=file_get_contents($filename);
if(trim($c)==''){$c='[]';}
$log =#json_decode($c,true);
if(!is_Array($log)){$log=[];}
}
$new=['mod'=>$mod,'date'=> date('Y-m-d H:i:s')." Scripttime: ".$diff."ms",'log'=>$str];
if($logOrder=='top'){
array_unshift($log , $new);
$log=array_slice($log,0,$maxLogs);
}else{
$log[]=$new;
$log=array_slice($log,0-$maxLogs,$maxLogs);
}
$logs=json_encode($log,128);
if(!file_put_contents($filename,$logs) ){echo ("Can’t open to write '$filename' Check Permissions") ;return;}
return $str;
}
?>
The Output looks like:
[
{
"mod": "delete",
"date": "2022-08-04 13:48:02 0.33ms",
"log": "test 2"
},
{
"mod": "start",
"date": "2022-08-04 13:48:29 0ms",
"log": "test"
},
{
"mod": "delete",
"date": "2022-08-04 13:48:29 0.27ms",
"log": "test 2"
}
]

Related

How do I create a new log file if my current log file is larger than 50mb in php?

I have a project where I have to make a new log file if the current log file is larger than 50mb. I know that we have to test for the size of the file.
I am starting out with this $log variable:
$log =
"Branch: ".$branchDir . PHP_EOL.
"Phase: ". $phaseDir . PHP_EOL.
"Total number of results files deleted: ". count($folderCounter). PHP_EOL.
"File names: " . $filePathToDelete . PHP_EOL.
"Starting CustomerID directory name: " . $CustIDvalue . PHP_EOL;
// $log = 'this is a test' . $branch . PHP_EOL;
$dt = time();
$mysql_datetime = strftime("%Y-%m-%d %H:%M:%S", $dt);
$mysql_datetimes = preg_replace('/\s+/', '', $mysql_datetime);
$logFileName = "ResultsFileDeletion" . $mysql_datetimes . ".txt";
if (unlink($filePathToDelete)) {
//this echo string will be moved to a log file
echo "first unlink: {$filePathToDelete} was deleted <br>";
$myFile =
file_put_contents("c:\\sites\\EtonBio/sequencing/logs/{$logFileName}",
$log, FILE_APPEND);
echo 'my file: ' . $myFile . '<br>';
}
I found this code snippet:
$size = filesize($_FILES['foto']['tmp_name']);
I believe my if statement would look something like this:
if($size < 52428800) {
*creates another log file
}
I want to format the $size variable correctly and I am also not sure how to make a new log file.
$size = filesize($_FILES['foto']['tmp_name']); only works if you are uploading the file.
If you want to check a file already in you server ou can simply do
$size = filesize("path/to/file");
Also, there is a ' in your $log declaration that shouldn't be there

PHP: Why file can only be written the first time and subsequent writes fail?

My code:
function log_message($user = "", $message = "") {
$log_file = LOG_PATH;
// if we can open the file
if($handle = fopen($log_file, "a")) {
$timestamp = strftime("%Y-%m-%d:%H %H:%M:%S", time());
$content = $timestamp . " | [{$user}] | " . $message . "\n";
fwrite($handle, $content);
fclose($handle);
} else {
die("error opening log file: {$log_file}");
}
}
Problem:
The first time I can write to the file no problem but any subsequent writes don't get make it through and falls into the else statement?
Other info:
The site is hosted on godaddy and i have set the privacy permissions on the folder to be writable.
What I tried:
I used the function
file_put_contents($log_file, $content . PHP_EOL, FILE_APPEND | LOCK_EX);
but same result.
I also tried the solution mentioned in this question: How to make sure a file handle has been closed before next operation?

Gearman addTaskBackground complete callback does not fire

I am trying to run some job in background and write the result to file result from complete callback, but it does only work for addTask (not in background) and not for addTaskBackground.
Does someone have an idea?
$client = new GearmanClient();
$client->addServer('localhost');
$client->setCompleteCallback("complete");
$client->addTaskBackground('upload', 'http://youtube.com/watch?v=o3mP3mJDL2k', null, 1);
$client->addTaskBackground('upload', 'http://www.youtube.com/watch?v=SgAVnlnf8w0', null, 2);
/* in these case complete callback works
$client->addTask('upload', 'http://youtube.com/watch?v=o3mP3mJDL2k');
$client->addTask('upload', 'http://www.youtube.com/watch?v=SgAVnlnf8w0');
*/
$client->runTasks();
function complete($task){
file_put_contents('/home/vonica/public_html/test/tmp/1.txt', $task->unique() . ", " . $task->data() . "\n", FILE_APPEND);
}
$worker = new GearmanWorker();
$worker->addServer('localhost');
$worker->addFunction('upload', 'uploader');
while($worker->work()){
if ($worker->returnCode() != GEARMAN_SUCCESS) {
echo "ret code: " . $worker->returnCode() . "\n";
break;
}
};
function uploader($job){
$content = $job->workload();
exec ('echo $( youtube-dl -f worst "'.$content.'")');
return $content;
}
CompleteCallback will not be called on background task completion. If you want to check the status of background job use GearmanClient::jobStatus.
Client.php
// save this $job_handle somewhere
$job_handle = $client->doBackground('upload', 'http://youtube.com/watch?v=o3mP3mJDL2k', null, 1);
Status.php
// use previously saved job handle to check job's status
$job_handle = $_GET['job_handle'];
$stat = $client->jobStatus($job_handle);
echo "Running: " .
($stat[1] ? "true" : "false") .
", numerator: " .
$stat[2] .
", denomintor: " .
$stat[3] . "\n";
Read more here

PHP fwrite() how to insert a new line after some specific line

I'm new here.
Anyway, I did my research on fwrite(), but I couldn't find solution, so i'm asking for help.
What I want is f.e. to add a new line of text after some other specific line.
F.e. I have a .txt file in which there is:
//Users
//Other stuff
//Other stuff2
Now what I'd like to do is be able to add a new user below //Users without touching "Other Stuff" and "Other Stuff 2". So it should look something like this:
//Users
Aneszej
Test321
Test123
//Other stuff
//Other stuff2
What I have so far:
$config = 'test.txt';
$file=fopen($config,"r+") or exit("Unable to open file!");
$date = date("F j, Y");
$time = date("H:i:s");
$username = "user";
$password = "pass";
$email = "email";
$newuser = $username . " " . $password . " " . $email . " " . $date . " " . $time;
while (!feof($file)) {
$line=fgets($file);
if (strpos($line, '//Users')!==false) {
$newline = PHP_EOL . $newuser;
}
}
fwrite($file, $newline);
fclose($file);
test.txt file
//Users
//Something Else
//Something Else 2
But this only writes users to the end of the .txt file.
Thanks a lot everyone for your help! It's solved.
I modified your code, I think follows is what you need, and I also put comment, function below will keep adding new user, you can add condition that to check user exist.
$config = 'test.txt';
$file=fopen($config,"r+") or exit("Unable to open file!");
$date = date("F j, Y");
$time = date("H:i:s");
$username = "user";
$password = "pass";
$email = "email";
$newuser = $username . " " . $password . " " . $email . " " . $date . " " . $time."\r\n"; // I added new line after new user
$insertPos=0; // variable for saving //Users position
while (!feof($file)) {
$line=fgets($file);
if (strpos($line, '//Users')!==false) {
$insertPos=ftell($file); // ftell will tell the position where the pointer moved, here is the new line after //Users.
$newline = $newuser;
} else {
$newline.=$line; // append existing data with new data of user
}
}
fseek($file,$insertPos); // move pointer to the file position where we saved above
fwrite($file, $newline);
fclose($file);
You write the new content at the end of the reading, so it has to write at the end of file - the cursor is there after reading all the lines.
Either you store all the content in php-variable and overwrite the file in the end, or you rewind the curser with fseek as mentioned by Robert Rozas comment. That should be done as soon as you read the "Something else" - line.
Try fseek:
<?php
$file = fopen($filename, "c");
fseek($file, -3, SEEK_END);
fwrite($file, "whatever you want to write");
fclose($file);
?>
PHP Doc: http://php.net/manual/en/function.fseek.php
You need to break after you find '//Users'. You keep reading to the end of the file.

Second instance of script runs the exact same code as the first one

This script is supposed to write log files using file locks etc to make sure that scripts running at the same time don't have any read/write complications. I got it off someone on php.net. When I tried to run it twice at the same time, I noticed that it completely ignored the lock file. However, when I ran them consecutively, the lock file worked just fine.
That doesn't make any sense whatsoever. The script just checks if a file exists, and acts based on that. Whether another script is running or not, shouldn't influence it at all. I double checked to make sure the lock file was created in both cases; it was.
So I started to do some testing.
First instance started at 11:21:00 outputs:
Started at: 2012-04-12 11:21:00
Checking if weblog/20120412test.txt.1.wlock exists
Got lock: weblog/20120412test.txt.1.wlock
log file not exists, make new
log file was either appended to or create anew
Wrote: 2012-04-12 11:21:00 xx.xx.xx.xxx "testmsg"
1
Second instance started at 11:21:03 outputs:
Started at: 2012-04-12 11:21:00
Checking if weblog/20120412test.txt.1.wlock exists
Got lock: weblog/20120412test.txt.1.wlock
log file not exists, make new
log file was either appended to or create anew
Wrote: 2012-04-12 11:21:00 xx.xx.xx.xxx "testmsg"
1
So there are two things wrong here. The timestamp, and the fact that the script sais the lock file doesn't exist even though it most certainly does.
It's almost as if the second instance of the script simply outputs what the first one did.
<?php
function Weblog_debug($input)
{
echo $input."<br/>";
}
function Weblog($directory, $logfile, $message)
{
// Created 15 september 2010: Mirco Babin
$curtime = time();
$startedat = date('Y-m-d',$curtime) . "\t" . date('H:i:s', $curtime) . "\t";
Weblog_debug("Started at: $startedat");
$logfile = date('Ymd',$curtime) . $logfile;
//Set directory correctly
if (!isset($directory) || $directory === false)
$directory = './';
if (substr($directory,-1) !== '/')
$directory = $directory . '/';
$count = 1;
while(1)
{
//*dir*/*file*.*count*
$logfilename = $directory . $logfile . '.' . $count;
//*dir*/*file*.*count*.lock
$lockfile = $logfilename . '.wlock';
$lockhandle = false;
Weblog_debug("Checking if $lockfile exists");
if (!file_exists($lockfile))
{
$lockhandle = #fopen($lockfile, 'xb'); //lock handle true if lock file opened
Weblog_debug("Got lock: $lockfile");
}
if ($lockhandle !== false) break; //break loop if we got lock
$count++;
if ($count > 100) return false;
}
//log file exists, append
if (file_exists($logfilename))
{
Weblog_debug("log file exists, append");
$created = false;
$loghandle = #fopen($logfilename, 'ab');
}
//log file not exists, make new
else
{
Weblog_debug("log file not exists, make new");
$loghandle = #fopen($logfilename, 'xb');
if ($loghandle !== false) //Did we make it?
{
$created = true;
$str = '#version: 1.0' . "\r\n" .
'#Fields: date time c-ip x-msg' . "\r\n";
fwrite($loghandle,$str);
}
}
//was log file either appended to or create anew?
if ($loghandle !== false)
{
Weblog_debug("log file was either appended to or create anew");
$str = date('Y-m-d',$curtime) . "\t" .
date('H:i:s', $curtime) . "\t" .
(isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '-') . "\t" .
'"' . str_replace('"', '""', $message) . '"' . "\r\n";
fwrite($loghandle,$str);
Weblog_debug("Wrote: $str");
fclose($loghandle);
//Only chmod if new file
if ($created) chmod($logfilename,0644); // Read and write for owner, read for everybody else
$result = true;
}
else
{
Weblog_debug("log file was not appended to or create anew");
$result = false;
}
/**
Sleep & disable unlinking of lock file, both for testing purposes.
*/
//Sleep for 10sec to allow other instance(s) of script to run while this one still in progress.
sleep(10);
//fclose($lockhandle);
//#unlink($lockfile);
return $result;
}
echo Weblog("weblog", "test.txt", "testmsg");
?>
UPDATE:
Here's a simple script that just shows the timestamp. I tried it on a different host so I don't think it's a problem with my server;
<?php
function Weblog_debug($input)
{
echo $input."<br/>";
}
$curtime = time();
$startedat = date('Y-m-d',$curtime) . "\t" . date('H:i:s', $curtime) . "\t";
Weblog_debug("Started at: $startedat");
$timediff = time() - $curtime;
while($timediff < 5)
{
$timediff = time() - $curtime;
}
Weblog_debug("OK");
?>
Again, if I start the second instance of the script while the first is in the while loop, the second script will state it started at the same time as the first.
I can't fricking believe this myself, but it turns out this is just a "feature" in Opera. The script works as intended in Firefox. I kinda wish I tested that before I went all berserk on this but there ya go.

Categories