1

I'm having a little issue with regexp, i know this isn't directly a magento issue though.

My goal is to get a sub printing of magento logs in the admin.

To do so, I've created the following method

public function getLog($logfile,$nbLine = null){
    $nbCharPerLineApproximative = 100;
    $nbLine = $nbLine == null?$this->getNbLineToPrint():$nbLine;
    $contents = null;
    try {
        $path = $this->directoryList->getPath('var').'/log/'.$logfile ;
        $fileSubContent = substr($this->driverFile->fileGetContents($path),- $nbLine * $nbCharPerLineApproximative);
        var_dump($fileSubContent);

        $re = '/\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}][[:print:]]{1,}/';
        preg_match_all($re, $fileSubContent, $contents, PREG_SET_ORDER, 0);
        var_dump($contents);
    } catch (FileSystemException $e) {
        var_dump($e->getMessage());
    }
    return $contents;
}

$fileSubContent, will get all the data perfectly. But the regex is messing with accent.

As an exemple the regexp will match

Paypal a rejete le paiement.

But it will only match

Paypal a rejet

if the real sentence is

Paypal a rejeté le paiement.

The main goal being to retrieve all data "logs by logs" and not just line by line

[2021-08-10 12:21:14] main.ERROR: Unable to unserialize value. [] [] [2021-08-10 12:25:45] main.ERROR: Paypal a rejeté la demande. [] []

1 Answer 1

1

Since you are saying 'log by log', I assume you want to create a regex to split like this:

[2021-08-10 12:21:14] main.ERROR: Unable to unserialize value. []
[2021-08-10 12:25:45] main.ERROR: Paypal a rejeté la demande. []

Then when you want to use the date and message, you may be able to do this:

(?<date>\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}])(?<message>.+?)(\[\])

Use preg_match_all as you already are, but now you have two benefits:

  1. Accents splitting correctly (removed :print:)
  2. Date and Message split for each item.
preg_match_all('/(?<date>\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}])(?<message>.+?)(\[\])/', $fileSubContent, $contents);

Then loop through each $contents and access the date and message keys, so ignore the indexed (0-n) items. This will mean indexed item $contents['message'][0] and $contents['date'][0] should be for the same row.

Test output

I removed the accent from the word to see if there are anything different, results look the same:

0   =>  array(4
0   =>  [2021-08-10 12:21:14] main.ERROR: Unable to unserialize value. []
1   =>  [2021-08-10 12:25:45] main.ERROR: Paypal a rejeté la demande. []
2   =>  [2021-08-10 12:21:14] main.ERROR: Unable to unserialize value. []
3   =>  [2021-08-10 12:25:45] main.ERROR: Paypal a rejete la demande. []
)
**date**    =>  array(4
0   =>  [2021-08-10 12:21:14]
1   =>  [2021-08-10 12:25:45]
2   =>  [2021-08-10 12:21:14]
3   =>  [2021-08-10 12:25:45]
)
1   =>  array(4
0   =>  [2021-08-10 12:21:14]
1   =>  [2021-08-10 12:25:45]
2   =>  [2021-08-10 12:21:14]
3   =>  [2021-08-10 12:25:45]
)
**message** =>  array(4
0   =>   main.ERROR: Unable to unserialize value. 
1   =>   main.ERROR: Paypal a rejeté la demande. 
2   =>   main.ERROR: Unable to unserialize value. 
3   =>   main.ERROR: Paypal a rejete la demande. 
)
2   =>  array(4
0   =>   main.ERROR: Unable to unserialize value. 
1   =>   main.ERROR: Paypal a rejeté la demande. 
2   =>   main.ERROR: Unable to unserialize value. 
3   =>   main.ERROR: Paypal a rejete la demande. 
2
  • 1
    I'm actually using this later to split the full message by his type so i don't really need to split in group like you did. But it looks way better written like you did, i think i will rewrite my code. But if you have a solution to get the full message at once i take it aswell :) ` public function splitMessageByType($message){ $type = "main.".$this->getMessageType($message).':'; return explode($type,$message); }`
    – Claims
    Commented Oct 11, 2022 at 11:35
  • 1
    Yeah, I also used to split regex strings 'afterwards', but I found most of the time grouped names in regex are so useful that I always try to use it in this fashion at the same time. Happy to have guided you, may you please accept the answer later on. Commented Oct 11, 2022 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.