Equivalent of PHP error_log for info logs? - php

I use error_log for my logging, but I'm realizing that there must be a more idiomatic way to log application progress. is there an info_log ? or equivalent ?

You can use error_log to append to a specified file.
error_log($myMessage, 3, 'my/file/path/log.txt');
Note that you need to have the 3 (message type) in order to append to the given file.
You can create a function early on in your script to wrap this functionality:
function log_message($message) {
error_log($message, 3, 'my/file/path/log.txt');
}

The equivalent is syslog() with the LOG_INFO constant:
syslog(LOG_INFO, 'Message');
If you want to use a file (not a good idea because there is no log rotation and it can fail because of concurrency), you can do:
file_put_contents($filename, 'INFO Message', FILE_APPEND);

I would recommend you to use Monolog:
https://github.com/Seldaek/monolog
You can add the dependency by composer:
composer require monolog/monolog
Then you can initialize a file streaming log, for an app called your-app-name, into the file path/to/your.log, as follow:
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('your-app-name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
Monolog is very powerful, you can implement many types of handlers, formatters, and processors. It worth having a look:
https://github.com/Seldaek/monolog/blob/master/doc/02-handlers-formatters-processors.md
And finally call it like:
// add records to the log
$log->warning('Foo');
$log->error('Bar');
In order to make it global, I recommend you to add it to your dependency injector, if you have one, or use a singleton with static calls.
Let me know if you want more details about this.

Related

How can i send Mails within my Typo3 extension

I get results from a jQuery Survey in JSON within my Typo3 Extension. Now I want to send these results with the Typo3 Mail API to my Inbox. According to the documentations following shoud do the work
$mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
$mail->from(new \Symfony\Component\Mime\Address('john.doe#example.org', 'John Doe'));
$mail->to(
new \Symfony\Component\Mime\Address('receiver#example.com', 'Max Mustermann'),
new \Symfony\Component\Mime\Address('other#example.net')
);
$mail->subject('Your subject');
$mail->text('Here is the message itself');
$mail->html('<p>Here is the message itself</p>');
$mail->attachFromPath('/path/to/my-document.pdf');
$mail->send();
so my code looks like this:
namespace TYPO3\CMS\Core\Mail;
if (!file_exists( dirname(__DIR__, 2).'/vendor/autoload.php' )) {
throw new \RuntimeException(
'Could not find vendor/autoload.php, make sure you ran composer.'
);
} else {
require dirname(__DIR__, 2).'/vendor/autoload.php';
}
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MailUtility;
$mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
$mail->from(new \Symfony\Component\Mime\Address('john.doe#example.org', 'John Doe'));
$mail->to(
new \Symfony\Component\Mime\Address('receiver#example.com', 'Max Mustermann'),
new \Symfony\Component\Mime\Address('other#example.net')
);
$mail->subject('Your subject');
$mail->text('Here is the message itself');
$mail->html('<p>Here is the message itself</p>');
$mail->attachFromPath('/path/to/my-document.pdf');
$mail->send();
I just getting errors. Does anyone know how i can achieve this?
Following error i get
Notice: Undefined index: TYPO3_CONF_VARS in /var/www/html/local_packages/ext_sitepackage/public/typo3/sysext/core/Classes/Mail/Mailer.php on line 170
Apparently this is the same question as you already posted here.
This will never work like this. You need to either build a fully fledged TYPO3 extension or a standalone application using symfony/mailer directly.
Your script is missing $GLOBALS['TYPO3_CONF_VARS']['MAIL'].
You stumble over the fact that you're programming past the conventions and requirements of TYPO3, but then you're surprised that the framework's functions don't work...
Create a middleware in your sitepackage, and register it correctly. Check for a special route and let the rest run. If handling, use the code there.
You need to run the mailing code in a (full) bootstrapped Typo3 context:
in a middleware
extbase plugin registered with pageNum directly
Your pasted code looks weired in a lot of ways. Just putting a file in a extension folder do not mean that is correctly a typo3 extension.
Maybe you want to start and have a proper extension setup first, with the corresponding readings:
ext_emconf.php / composer.json as a minimum
code files in 'Classes/' subfolders
then decide with which way you want to handle the "ajax" call and send the email, there are several possibilities (as already mentioned above) .. than read and implement that solution the proper and correct way.
Just having a php file directly referenced/called and just bootstpping the composer autoloader do not and never will be bootstrapping Typo3 with all needed configuration bootstrapping (gathering confings from extensions, Local/AdditionalConfiguration, siteconfig and and and).
And generally a package/extension should have a namespace something like following (as a convention):
<extensionname.....
an thus registered as psr-4 autoloading in your extension composer.json ..
Starting to implement the peaces to simulate a Typo3 bootstpraping in that file is not good and will make a lot of headache ... it's easier to have a proper sitepacke/extension structure.

Can Monolog be used on GAE and have the logging levels recorded in Stack Driver?

There are a number of posts on the internet that indicate the right way to use Monolog on the google app engine (GAE standard) is like so:
$logger = new Monolog\Logger($name);
$syslogHandler = new \Monolog\Handler\SyslogHandler("Ident_String", LOG_USER, \Monolog\Logger::INFO);
$syslogHandler->setFormatter(new \Monolog\Formatter\JsonFormatter());
$logger->pushHandler($syslogHandler);
break;
$logger->warn("Starting priam import." );
That does get me logging, but the level is buried in the textPayload:
textPayload: "[28-Feb-2020 11:00:07] WARNING: [pool app] child 22
said into stderr: "[2020-02-28 06:00:07] match_old.INFO: Doing a super
huge SELECT to get all intls. [] []""
and the level icon is always a stippled out asterisk.
Has something changed? I'm using the php 7.3 run-time on GAE standard. Is there a way to use Monolog on GAE that let's you take proper use of stack driver?
There is a package available that allows you to push Monolog to Stackdriver.
As per the doc:
The supplied StackdriverHandler copies the given log level into the
Stackdriver's severity based on your log method.
It also respects the context argument which allows you to send extra
contextual data with your log message. This will be stored in the log
message under jsonPayload.data.
The source code can be found here monolog-stackdriver
I wound up conditionally loading a different logger locally than I do on GAE. It's workable, but it seems like an unnecessary hack considering monolog is such a popular library. And, oh, it's 2020.
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use Google\Cloud\Logging\LoggingClient;
function get_logger($name) {
$kind = getenv('LOG_TYPE')?:'remote';
return _get_logger($kind, $name);
}
function _get_logger($kind, $name) {
if ($kind ==='local') {
$logger = new Monolog\Logger($name);
$logger->pushHandler(new Monolog\Handler\StreamHandler('php://stdout', Monolog\Logger::INFO));
return $logger;
}
$logging = new LoggingClient();
$logger = $logging->psrLogger($name);
return $logger;
}
I'm hoping someone can make this work with monolog.

How to use php monolog

I've heard a lot about monolog(https://github.com/Seldaek/monolog) & trying to use that in one of our app. But, can't able to fig. out how to use that. Don't know it's I'm only can't able to get any documentation of it or really it has no documentation at all.
We want to log all our errors in DB & as well as send an email notification about error when it'll get generate. For sending email we are using Swiftmailer(swiftmailer.org).
I can be able to run this sample code from Github link,
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
// add records to the log
$log->addWarning('Foo');
$log->addError('Bar');
but can't able to understand how to use this with DB & any other email library.
You posted an example yourself. Instead of StreamHandler use one or more of the other handlers that monolog is offering.
You have to look into the code of the handlers to see which dependencies they need. Look inside the Monolog directory and you'll find the Handler classes. Code is the most reliable documentation.
<?php
use Monolog\Logger;
use Monolog\Handler\SwiftMailerHandler;
use Swift_Mailer;
// ... more dependencies you need
// create your Swift_Mailer and Swift_Message instances
$handlers = [
new SwiftMailerHandler($swiftMailer, $swiftMessage),
// add more handler you need
];
$log = new Logger('name', $handlers);
$log->warning('Foo');
$log->error('Bar');
You have to create a Swift_Mailer and Swift_Message instance for the SwiftMailerHandler. Instead of pushHandler, you can add an array of handlers into the Logger constructor.
The Swift_Message instance is used for every log message where the message replaces every time the mail body.
I can only suggest to you to read the monolog code for information where a further documentation is missing.

PHP: How to use monolog to log to console (php://out)?

I just switched to monolog and wanted to log my message to the PHP console instead of a file. This might seem obvious for some people, but it took me a little while to figure out how to do that and I couldn't find a similar question/answer on SO.
The example on Monolog's Github readme only shows how to use a file:
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING)); // <<< uses a file
// add records to the log
$log->addWarning('Foo');
$log->addError('Bar');
But it doesn't state anywhere how messages can be logged to the console. After searching on Google, I landed either on a help page for Symfony or questions of people looking for a way to log to the browser console.
The solution is rather simple. Since the example shows a StreamHandler it's possible to pass in a stream (instead of the path to a file). By default, everything that is echo'ed in PHP is written to php://stdout / php://output so we can simple use one of those as stream for the StreamHandler:
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('php://stdout', Logger::WARNING)); // <<< uses a stream
// add records to the log
$log->warning('Foo');
$log->error('Bar');
Hope this saves somebody some time :)
Some extra details if you want to tweak the default message formatting at the same time:
use Monolog\Logger;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
$output = "[%datetime%] %channel%.%level_name%: %message%\n";
$formatter = new LineFormatter($output);
$streamHandler = new StreamHandler('php://stdout', Logger::DEBUG);
$streamHandler->setFormatter($formatter);
$logger = new Logger('LoggerName');
$logger->pushHandler($streamHandler);

Passing parameters to my custom logger in symfony

I am having some troubles using the logger service in Symfony2. I find it quite confusing.
I am trying to use a Rotating File Handler. To this handler zou can pass 3 paramenters: the filename of the log, maxFiles that the log can divide itself and log level.
I want to pass this parameters from the controller, since I load that data in runtime from a .ini configuration file, but I am not sure how to do it.
How could I do this?
Try the following in your controller:
add a use statement: use Monolog\Handler\RotatingFileHandler;
use it like this: $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);

Categories