MRP Log - Stop Appending & Clean Up Files

Hello,

We have Scheduled the MRP Process to run daily and it looks like each new Log file gets appended to the original. Epicor 9 used to just write over the file each time.

Is this a setting that could be changed somewhere? Or does anyone know of a way that I can tack on a date stamp to these logs so we could keep a few of them? And is there a process to clean them up because that doesn’t look like it is working for us?

I’d appreciate any help anyone could give with this.

Thank you!
-Heather :slight_smile:

1 Like

I’d be curious about this as well. If there is a setting that could be changed, that would definitely be easiest. If not, I had started a powershell script that would email a list of any Part Numbers that were ‘abandoned’ in the MRP process, and then archive the log file each day with a timestamp. I’d be much more likely to finish that if we were both dependent on it!

2 Likes

I wondered if it might come down to a Powershell script to save the file under a different name each time and to clean up old files but I thought I’d put a feeler out there to see if there was a setting and process already in place before I went that route. :slight_smile:

I’m surprised that it isn’t at least working like it did in E9 where the MRP Log got overwritten each time but instead it gets appended and just grows and grows. And it always seemed as if our other log\report files got cleaned up regularly but that doesn’t seem to be the case with these EpicorData\Companies…\Log,Process,Temp folders. :thinking:

Can I ask what you mean by ‘abandoned’ and what sort of message you are seeing with that? I’m also trying to look for errors in our MRP logs like “defunct”, “deadlock” (although I think we might have eliminated these by pulling back on the number of Schedulers we are running), and “error occurred while reading from the store provider’s data reader” but I’ve been told that I can ignore the last one??? :face_with_raised_eyebrow:

Oh! Now that I perform a search for “abandoned” I guess I see that it is associated to our “defunct” issue. It does seem that we eliminated both the “abandoned/defunct” and “deadlock” issues when we halved the number of Schedulers that we were using. I think the problem might have occurred when too many schedulers were trying to grab the same resources? We need to try to tweak it to see if we can increase that number without running into those errors again.

You do have MRP scheduled, correct?

We were running into issues where MRP appeared to be hung. When I started looking into it, I found that the “Abandoned” lines of the MRP log reflected part numbers that were failing to run through MRP. It turns out that MRP will attempt to resolve part number issues on the fly, but it tries to resolve them for something like 1-2 hours by default (don’t quote me on that). In any case, while it’s trying to resolve it, it locks out the MRP Processor. We had several problematic parts, and it ended up using up all of our available MRP Processors so it appeared to be hung. If we would have let it run for something like 6 hours, it would have finished and just skipped over those parts. MRP normally takes 45 minutes for us, so that would never fly!

Eventually the part numbers were fixed and the problem went away naturally, but since then I’ve had extra logging enabled. The goal was to archive each log daily, and at the same time identify any parts in the MRP log that could be causing an MRP issue. The script would have emailed the engineering team a list of “abandoned” part numbers and then archived the log for the day. “Abandoned” happened to be my keyword, although defunct probably works as well.

1 Like

Hi @Kimberley,

Yes, this is a scheduled MRP process. (Sits in scheduled tasks in system monitor) :slight_smile:

Thanks,
-Heather

I just happened to finish writing and testing a Powershell script today that

  1. checks the MRP logs for errors,
  2. sends an email with the error lines to an admin and a planner,
  3. renames the log files by appending the date,
  4. purges all files older than 7 days.
    It is unsophisticated code with many hard coded filenames and line by line parsing rather than any cool Powershell object handling, so it would require tweaking to work in any other environment.

Our daily MRP run is a process set that includes the MRP process, followed by Calc Global Schedule Order process, followed by the Global Scheduling process. Each is set to verbose logging.

I search for “Error” in the MRP log, and I search for “not” in the Scheduling log, because that captured all the errors our test logs have. Let me know if there are other text strings that should be included.

# This powershell script processes the log files MRP and Global Scheduler at the end of each MRP run and sends email with errors.  
# Then the files are renamed and saved as archives

# this file resides and is normally run from \\xxxxxxx\UD\
# Windows Task Scheduler runs this program every night at 4:00 am  
# The MRP process set runs at 3:00 am by Epicor Task Agent and includes 1. MRP, 2. Calc Global Schedule Order, and 3. Global Scheduling

# Rev 1 2018-1-17

$Path = "D:\EpicorData\Companies\PP\Log\manager"
Set-Location -Path $Path
$DateString = (Get-Date -format yyyy-MM-dd)
Start-Transcript -Path "$Path\PowerShell-$DateString.log"  #logs any PowerShell errors to a log file in with the MRP logs

# Exit this PowerShell script if a MRP.Log does not exist
if (-not (Test-Path MRP001.LOG)) {Exit}

# Process MRP001.log
$AllLines = Get-Content MRP001.Log
$EmailBody = $AllLines[0] # this should put the time and date of the MRP run in the email body
$EmailBody = $EmailBody + "`r`nMRP Log - scan for 'Error'`r`n"
$LastErrorLine = 0
$i = 1
While ($i -lt $AllLines.Count) 
{
    if ($AllLines[$i] -Match "Error") 
    {
        If ($AllLines[$i-1] -eq $AllLines[$LastErrorLine])
        {
        # skip if it's a duplicate error
        }
        Else 
        {
        $EmailBody = $EmailBody + $AllLines[$i-1] + "`r`n" + $AllLines[$i] + "`r`n"
        $LastErrorLine = $i-1
        }
    }
    $i++
}
#done with MRP001

# Process MRP002.log
$AllLines = Get-Content MRP002.Log
$LastErrorLine = 0
$i = 1
While ($i -lt $AllLines.Count) 
{
    if ($AllLines[$i] -Match "Error") 
    {
        If ($AllLines[$i-1] -eq $AllLines[$LastErrorLine])
        {
        # skip if it's a duplicate error
        }
        Else 
        {
        $EmailBody = $EmailBody + $AllLines[$i-1] + "`r`n" + $AllLines[$i] + "`r`n"
        $LastErrorLine = $i-1
        }
    }
    $i++
}
#done with MRP002

# Process MRPsched001.log
$AllLines = Get-Content MRPsched101.Log
$MyRegex = '((?:January|February|March|April|May|June|July|August|September|October|November|December)\s\d{1,2}\s\d{4})|\d{1,2}\/\d{1,2}\/\d{4}'
$GraceDays = 7
$i = 1

$EmailBody = $EmailBody + "`r`nGlobal Schedule Log - scan for 'not' with jobs more than 7 days late.`r`n"

While ($i -lt $AllLines.Count) 
{
    if ($AllLines[$i] -Match "not") 
    {
    # found a line that is not meeting schedule for some reason
    # See if there are two dates in the line with 'not' in it
    $MMM = Select-String -InputObject $AllLines[$i] -Pattern $MyRegex -AllMatches | foreach {$_.Matches}
    if ($MMM -eq $NULL)
        {               # no dates found, so include the lines
#        $AllLines[$i-1] 
#        $AllLines[$i]
        $EmailBody = $EmailBody + $AllLines[$i-1] + "`r`n" + $AllLines[$i] + "`r`n"
        }
        ELSE
        {               # dates were found, check if more than the grace period late
        $Date1 = [DateTime]$MMM.Groups[0].Value  # not sure why this needs to be Groups[0] and Groups[2] (not Groups[1])
        $Date2 = [DateTime]$MMM.Groups[2].Value
#        $Date1
#        $Date2
        If (($Date1 - $Date2).Days -gt $GraceDays)
            {           # dates are greater than grace period, so include the lines
#            $AllLines[$i-1]
#            $AllLines[$i]
            $EmailBody = $EmailBody + $AllLines[$i-1] + "`r`n" + $AllLines[$i] + "`r`n"
            }
        }
    }
    $i++
}
# done with MRPsched001

# Process MRPsched002.log
$AllLines = Get-Content MRPsched102.Log
$MyRegex = '((?:January|February|March|April|May|June|July|August|September|October|November|December)\s\d{1,2}\s\d{4})|\d{1,2}\/\d{1,2}\/\d{4}'
$GraceDays = 7
$i = 1

While ($i -lt $AllLines.Count) 
{
    if ($AllLines[$i] -Match "not") 
    {
    # found a line that is not meeting schedule for some reason
    # See if there are two dates in the line with 'not' in it
    $MMM = Select-String -InputObject $AllLines[$i] -Pattern $MyRegex -AllMatches | foreach {$_.Matches}
    if ($MMM -eq $NULL)
        {               # no dates found, so include the lines probably some other error
#        $AllLines[$i-1] 
#        $AllLines[$i]
        $EmailBody = $EmailBody + $AllLines[$i-1] + "`r`n" + $AllLines[$i] + "`r`n"
        }
        ELSE
        {               # dates were found, check if more than the grace period late
        $Date1 = [DateTime]$MMM.Groups[0].Value  # not sure why this needs to be Groups[0] and Groups[2] (not Groups[1])
        $Date2 = [DateTime]$MMM.Groups[2].Value
#        $Date1
#        $Date2
        If (($Date1 - $Date2).Days -gt $GraceDays)
            {           # dates are greater than grace period, so include the lines
#            $AllLines[$i-1]
#            $AllLines[$i]
            $EmailBody = $EmailBody + $AllLines[$i-1] + "`r`n" + $AllLines[$i] + "`r`n"
            }
        }
    }
    $i++
}
#done with MRPsched002

Send-MailMessage -From MRP@ppsystems.com -Subject "MRP Log Results" -To "xxx@ppsystems.com, xxx@ppsystems.com" -Body $EmailBody -SmtpServer 10.0.0.5

# rename files to be ready for the next day
Rename-Item MRP.log ("MRP-" + $DateString + ".log")
Rename-Item MRP001.log ("MRP001-" + $DateString + ".log")
Rename-Item MRP002.log ("MRP002-" + $DateString + ".log")
Rename-Item MRPsched101.log ("MRPsched101-" + $DateString + ".log")
Rename-Item MRPsched102.log ("MRPsched102-" + $DateString + ".log")
Rename-Item GlobalSched.log ("GlobalSched-" + $DateString + ".log")
Rename-Item GlobalSchedsched001.log ("GlobalSchedsched001-" + $DateString + ".log")
Rename-Item GlobalSchedsched002.log ("GlobalSchedsched002-" + $DateString + ".log")
Rename-Item CalcSchedOrder.log ("CalcSchedOrder-" + $DateString + ".log")
Rename-Item CalcSchedOrdersched001.log ("CalcSchedOrdersched001-" + $DateString + ".log")
Rename-Item CalcSchedOrdersched002.log ("CalcSchedOrdersched002-" + $DateString + ".log")

# Delete all Files in $Path older than 7 day(s)
$Daysback = "-7"
$CurrentDate = Get-Date
$DatetoDelete = $CurrentDate.AddDays($Daysback)
Get-ChildItem $Path | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item

Stop-Transcript
7 Likes

AWESOME @alintz! Thank you SO MUCH for sharing this! I’m going to look at this PS script and see if I can tweak it for us to use as well. Seems like it does everything we wanted to do with our MRP Logs! The only other text strings we search for are “deadlock” and “defunct” (I hope these have been eliminated by pulling back on our schedulers but early on, those are the errors we were running into) and “provider’s” (which comes from the “error occurred while reading from the store provider’s data reader” - which we were told we could ignore but “I just can’t do it Captain…” and would still like them reported.)

image

After running for the first time on real data last night, I modified the send email section to correct the syntax of multiple email recipients, and to prevent the email from being sent if there was no errors found. So here is what that section should look like:

if ($EmailBody.Length -ge 170) 
{
Send-MailMessage -From MRP@ppsystems.com -Subject "MRP Log Results" -To "xxx@ppsystems.com", "xxx@ppsystems.com" -Body $EmailBody -SmtpServer 10.0.0.5
}
3 Likes

How did you fix your Parts? What was wrong with them? kinda running into the same situation on 500.31

We had MRP quit on us last night running 10.1.600.8. Has anyone figured out what might be wrong with the parts that we need to fix?

19:30:35 Process 3 not responding. Abandoned during process ‘Defunct : Processing Part~201-0537-01’
19:51:27 Process 2 not responding. Abandoned during process ‘Defunct : Processing Part~4100163’
20:14:32 Process 1 not responding. Abandoned during process ‘Defunct : Processing Part~4100570’

Hi @kfierce,

Are you also seeing deadlock messages in your MRP logs as well? I think the “Abandoned” and “Defunct” (what a great name for a Rock Band! LOL :guitar:) processes are the result of Deadlocks where two processes are trying to compete for the same resources. So SQL will grant one process access to the resources it needs while I’m assuming the other process becomes “Defunct”…(at least that’s kind of my understanding of it.)

What we did to resolve the deadlock\defunct problem was we decreased the number of Schedulers we were using therefore decreasing the possibility of two processes competing for the same resources at the same time. (Thank you for your help WarrenG @ Epicor! :wink: ) Warren mentioned that another customer of his was experiencing the same issue and when they lowered the number of schedulers they were using that fixed this issue for them as well.

We were running MRP with 4 Processes and 8 Schedulers but when we changed to using 4 Processes and 4 Schedulers it eliminated the deadlock\defunct issue.

I’d still like to see what increasing the number of schedulers by one or two does until we can find the “sweet spot” to running MRP as quickly as possible without this issue.

We never had any issues with our parts. And it never seemed to be the same parts that would get Defunct-ed (is that the appropriate form of that word?) every time. And the parts that were showing as defunct have been able to be processed successfully through MRP before - so I knew there weren’t any problems with these parts necessarily.

@GaryL, you mentioned that “Eventually the part numbers were fixed” … what did you do to fix these part numbers? Thanks!

@ERPSysAdmin @hkeric.wci I can’t say I know exactly ‘how’ they were fixed, but I turned it over to our Engineers who knew that those were newly created parts. They agreed to take a look at the parts to see if they missed something on the setup, and if they couldn’t find anything they figured they would just re-create the parts. The next day, the parts were no longer in the log.

After further research I determined MRP stalled for us last night due to bad dates imported from a 3rd party application on a sales order with these three parts. In our case MRP probably did not know what to make of the need by/ship by date. It imported as 01/01/01.
Order dates has been updated so we don’t anticipate to see MRP stall for these three parts again tonight.

1 Like

Thank you Andrew for posting this. It will be very helpful for me also. I am searching and deleting the file manually currently.

Angie

Our Issue was we are using Min and Max Lot Sizes of 1 in the Planning tab and the Sales Order Releases have high Quantities 70-300 and Epicor just cant handle it fast enough or properly for whatever reason.

Splitting it up into multiple releases did the trick. I would consider this a fault of Epicor’s but we have a workaround.

Andrew,
You may also want to add a Stop-Transcript in your MRP.Log check:

# Exit this PowerShell script if a MRP.Log does not exist
if (-not (Test-Path MRP001.LOG)) 
{
    Stop-Transcript
    Exit
}
1 Like

Good idea, Rick. Thanks.
Here’s my latest code for when no MRP log is found - it now sends me an email, stops the transcript, and exits:


# Exit this PowerShell script if a MRP.Log does not exist
if (-not (Test-Path MRP001.LOG)) 
    {
    $EmailBody = $EmailBody + "No MRP001.LOG file found.  Exiting PowerShell.`r`n"
    $EmailBody  # this forces the text of the email into the transcript
    Send-MailMessage -From MRP@ppsystems.com -Subject "MRP Log Results" -To "xxx@ppsystems.com" -Body $EmailBody -SmtpServer 10.0.0.5
    Stop-Transcript
    Exit
    }
2 Likes

There are several issues that could MRP to complete but not schedule a job or delete an MRP job. We created a dashboard that users could look at to pulls parts with potential issues with parts. Here are some examples of issues …

No Approved Rev on Mfg part
Approved Rev in wrong plant (if multi plant)
Resource from another Plant on Method
Part Inactive on Method
Lock on Part or Job (someone has it opened)

This may be the long way around but we typically look at the main log to see if any parts abandoned then look at the log for those processes to see where it failed. Then I open all the log files in Notepad++ and search for Type:3 (Find in all opened documents) It will give you results below of issues. Now MRP will still run complete with these issues but jobs may not get created or not scheduled. You can then click on each line and dig deeper if needed. I usually send the results out after I polish them up.

Here is a screen shot of my logs…

2 Likes

If there are any errors in the routing with specified resource groups on routings (most notably a resource being flagged inactive, or a resource specified that does not exist in the group), the planned jobs do not schedule.

I run two views to check on MRP failures - planning workbench (identifies items that did not have unfirm jobs created) and Order Entry (identifies planned jobs that did not schedule - sort by Due Date, it will be blank).

Fortunately, we have the process to correct these findings nailed down pretty well. Also, we have incorporated a process which allows checking of the routing construction at the time of method approval, which allows a second set of eyes to look for items that would cause either of these failures to occur.

1 Like