Single log for each file Serilog - FileSink class Obsolete Error - serilog

I want to create a seperate log file for each HTTP request made to the application. When ever a request is made to the application, it has to generate a log file in the following format
debug20220713.log
debug20220713_001.log
debug20220713_002.log
Here in each log file there should be only one log available.
Log.Logger = new LoggerConfiguration()
.Enrich.WithExceptionDetails()
.Enrich.FromLogContext()
.WriteTo.Async(y =>
y.Logger(m =>
{
m.WriteTo.File(
new ExpressionTemplate(jsonErrorTemplate),
"error.log", LogEventLevel.Warning,
rollingInterval: RollingInterval.Day);
m.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Warning || e.Level == LogEventLevel.Error);
})
)
.WriteTo.Async(x =>
x.Logger(l =>
{
l.WriteTo.File(new ExpressionTemplate(jsonLogTemplate),
"debug.log", LogEventLevel.Information,
rollingInterval: RollingInterval.Day);
l.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Information);
}))
.CreateLogger();
I ended up creating own verision of RollingFileSink which matches my requirement. but internally I still use FileSink class. When I call constructor of FileSink I get this error
"This type and constructor will be removed from the public API in a future version; use WriteTo.File() instead."

Related

Serilog logs on Console below minimum level

I defined a Logger this way with LogLevel FATAL for Console log:
LoggerConfiguration logCfg = new LoggerConfiguration();
logCfg
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Error)
.Enrich.FromLogContext()
.Enrich.With(new UtcTimestampEnricher())
.Enrich.WithProperty("SENDER", applicationName)
//ToDo, extend the Logger for DB to log an active GUID
//.Enrich.WithProperty("GUID", guid)
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Fatal)
.WriteTo.File(applicationLogPath,
restrictedToMinimumLevel: logEventLvlFile,
outputTemplate: fileOutputTemplate,
rollOnFileSizeLimit: changeOnFileSizeLimit,
fileSizeLimitBytes: fileSize,
retainedFileCountLimit: retainedFileCount);
But this will be displayed on Console:
_logger.LogInformation("Worker pulling config at: {time}", DateTimeOffset.Now);
This was the solution:
foreach (ServiceDescriptor serviceDescriptor in logging.Services)
{
if (serviceDescriptor.ImplementationType == typeof(Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider))
{
// remove ConsoleLoggerProvider service only
logging.Services.Remove(serviceDescriptor);
break;
}
}
logging.AddSerilog();

Write this serilog filter in config file

Usually, I set the configuration of .NET applications inside the config file (appsettings.json or *.config file, it depends if it's .NET Core or .NET Full Framework).
Now for the first time, I had to use a filter, and I'm not able to write such logic inside the config file.
Here's the logic I wish to bring to the config file
var logConfiguration = new LoggerConfiguration()
//.ReadFrom.AppSettings()
.WriteTo.Logger(lc => lc.WriteTo.EventLog(environmentSettings.ServiceNameInstanceForMonitor, manageEventSource: true)
.Filter.ByIncludingOnly(pred =>
{
if (!pred.Properties.ContainsKey("Destination")) return false;
return pred.Properties["Destination"].ToString().Contains("EventLog");
}))
.Enrich.WithExceptionDetails()
.Enrich.WithAssemblyVersion(true)
.WriteTo.Console()
.WriteTo.Logger(lc2 => lc2.WriteTo
.File($"{AppDomain.CurrentDomain.BaseDirectory}\\logs\\{environmentSettings.ServiceNameInstanceForMonitor}-.log",
rollingInterval: RollingInterval.Day)
.Filter.ByExcluding((pred =>
{
var res = pred.Properties.ContainsKey("Destination") &&
pred.Properties["Destination"].ToString().Contains("EventLog");
return res;
})));
Is it possible?

Serilog, one file sink writing, one is leaving a blank file

So I have a simple method to make logger instances for me.
It is as follows
protected ILogger GetIndividualLogger(ILogger parentLogger, LogEventLevel minimumLevel, string RootDir, string Type, string Name, bool shouldBuffer, bool shouldBeShared, TimeSpan flushToDiskInterval)
{
var LogAllFile = $"{RootDir}{Path.DirectorySeparatorChar}{Name}{Path.DirectorySeparatorChar}RAL-{Type}-{Name}-.log";
var LogWarningFile = $"{RootDir}{Path.DirectorySeparatorChar}{Name}{Path.DirectorySeparatorChar}Warnings{Path.DirectorySeparatorChar}RAL-{Type}-{Name}-.log";
ILogger logger = new LoggerConfiguration()
.MinimumLevel.Is(minimumLevel)
.Enrich.WithDemystifiedStackTraces()
.WriteTo.Async(a => a.Logger(parentLogger))
.WriteTo.Async(a => a.File(LogAllFile, outputTemplate: SerilogHereHelper.TemplateForHere, rollingInterval: RollingInterval.Day, buffered: shouldBuffer, shared: shouldBeShared))
.WriteTo.Async(a => a.File(LogWarningFile, restrictedToMinimumLevel: LogEventLevel.Warning, outputTemplate: SerilogHereHelper.TemplateForHere, rollingInterval: RollingInterval.Day, buffered: shouldBuffer, shared: shouldBeShared, flushToDiskInterval: flushToDiskInterval))
.CreateLogger();
return logger;
}
Here is an example call to GetIndividualLogger
GetIndividualLogger(parentLogger: mainLogger, minimumLevel: LogEventLevel.Information, RootDir: _stackLightLogPath, Type: "Stack Light", Name: "Stack Light 1", shouldBuffer: true, shouldBeShared: false, flushToDiskInterval: TimeSpan.FromSecond(2))
The warning level sink will write, but then the other sink, which is usually set to debug or information will create an empty file but never add any entries to it.
I would expect both files to have all warning level entries or above.
I would expect the "LogAllFile" to have all entries at or above the minimum level, but it is blank.
Is there something wrong with my logger config? or is my problem elsewhere?
So the answer to the problem was silly. The warning log was being flushed to disk every 2 seconds, but the main log file was not so all I needed to do was to just pass a value in for flushToDiskInterval
.WriteTo.Async(a => a.File(LogAllFile, outputTemplate: SerilogHereHelper.TemplateForHere, rollingInterval: RollingInterval.Day, buffered: shouldBuffer, shared: shouldBeShared, flushToDiskInterval: flushToDiskInterval))

Request GetHumanStatus{model: ArrayObject} is not supported: ZF2

Creating a model for Sofort integration and extend the payments object from the payum module to use it in the capture.
<?php
namespace Reisesparer\Model;
use Payum\Core\Model\Payment;
class SofortueberWeisung extends Payment
{
protected $id;
}
Controller method for the sofort is like follows: I have created a seperate Model where extend to the payments object
public function sofortAction()
{
$storage = $this->getServiceLocator()->get('payum')->getStorage('Reisesparer\Model\SofortueberWeisung');
$payment = $storage->create();
$payment->setNumber(uniqid());
$payment->setCurrencyCode('EUR');
$payment->setTotalAmount(123); // 1.23 EUR
$payment->setDescription('A description');
$payment->setClientId('anId');
$payment->setClientEmail('foo#example.com');
$storage->update($payment);
$captureToken = $this->getServiceLocator()->get('payum.security.token_factory')->createCaptureToken(
'sofort', $payment, 'payment_done'
);
// print_r($captureToken);
// exit();
$this->redirect()->toUrl($captureToken->getTargetUrl());
}
And My config file has follows code to configure the payum/sofort mehthod in my project.
'sofort' => $sofortFactory->create(array(
'factory' => 'sofort',
'config_key' => '12345:123456:edc788a4316ce7e2ac0ede037aa623d7',
)),
And at the last my done action to capture the useful information after the successful payment is like follows:
public function doneAction()
{
$token = $this->getServiceLocator()->get('payum.security.http_request_verifier')->verify($this);
$gateway = $this->getServiceLocator()->get('payum')->getgateway($token->getgatewayName());
$gateway->execute($status = new GetHumanStatus($token));
$payment = $status->getFirstModel();
$viewModel = new ViewModel(array('status' => $status->getValue(),'details'=>$payment));
$viewModel->setTemplate('layout/pay_done');
return $viewModel;
}
Storage Config:
'storages' => array(
$detailsClass => new FilesystemStorage(__DIR__.'/../../data', $detailsClass, 'id'),
$paymentClass => new FilesystemStorage(__DIR__.'/../../data', $paymentClass, 'id'),
)
Now when ever i proceed with the sofort payment method to capture the payment it gaves me the error and not proceed further. but the other method like paypal, stripe and authorized.net are working fine in the same project how to resolve this issues
Error:
Request GetHumanStatus{model: ArrayObject} is not supported.

Can't get Task to Send Email in Symfony 1.4

I created a task to automate emailing a report in Symfony 1.4. Both this task and a related module for viewing in the web share a custom PHP class file. The task is able to pull in the data correctly, but I have not been able to get it to send out the email. I attempted to follow the official Symfony 1.4 documentation as well as a number of examples from a Google search, but none are solving my problem. The terminal isn't displaying any error either.
My Code:
<?php
require_once sfConfig::get('sf_lib_dir').'/vendor/sesame/reports/reports.class.php';
//use reports;
class reportsTask extends sfBaseTask
{
protected function configure()
{
// // add your own arguments here
// $this->addArguments(array(
// new sfCommandArgument('my_arg', sfCommandArgument::REQUIRED, 'My argument'),
// ));
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'),
new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'),
new sfCommandOption('type', null, sfCommandOption::PARAMETER_OPTIONAL, 'The output type of the report', 'email')
// add your own options here
));
$this->namespace = '';
$this->name = 'reports';
$this->briefDescription = '';
$this->detailedDescription = <<<EOF
The [reports|INFO] task does things.
Call it with:
[php symfony reports|INFO]
EOF;
}
protected function execute($arguments = array(), $options = array())
{
$databaseManager = new sfDatabaseManager($this->configuration);
$databaseManager->loadConfiguration();
$reports = new reports();
$output = $reports->buildReport($options['type']);
switch($options['type']){
case 'csv':
echo $output;
break;
case 'email':
$message = $this->getMailer()->compose($output['from'], $output['to'], $output['subject']);
$message->setBody($output['body']['content'], $output['body']['type']);
$message->attach(Swift_Attachment::newInstance($output['attachment']['content'], $output['attachment']['name'], $output['attachment']['type']));
$this->getMailer()->sendNextImmediately()->send($message) or die('email failed to deliver');
$output = array('status'=>'success', 'to'=>$output['to']);
default:
$this->logSection('results', json_encode($output));
}
}
}
The terminal command being attempted from the project root:
php symfony reports
Any answers leading to the right path would be most helpful. Please keep in mind that I need to stay with version 1.4. The server is capable of sending off emails and my module version does just that when invoked by a URL. I need it to run on the command line though so I can set up a cron.

Resources