New Question
 
 
PRTG Network Monitor

Intuitive to Use.
Easy to manage.

200.000 administrators have chosen PRTG to monitor their network. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free PRTG
Download >>

 

What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general. You are invited to get involved by asking and answering questions!

Learn more

 

Top Tags


View all Tags


Can I use placeholders in file names to monitor log files?

Votes:

0

Your Vote:

Up

Down

I want to monitor log files with PRTG. The names of these files contain the date of their creation like, for example, the PRTG webserver logfiles: prtg20160114.log

Because the native file sensor in PRTG does not allow placeholders for the file name, this is not the best option for me to monitor such log files. Is there a way to monitor time stamps and recent changes in the content of files using placeholders in the name for the target file?

custom-script-exe custom-sensor file file-name logfile placeholders powershell prtg

Created on Jan 21, 2016 1:19:39 PM by  Gerald Schoch [Paessler Support]



21 Replies

Accepted Answer

Votes:

0

Your Vote:

Up

Down

This article applies to PRTG Network Monitor 15 or later

Monitoring Files Using Placeholders

The File sensor that comes out of the box with PRTG can monitor a specific file on a disk if you provide the exact path and file name in the sensor settings. This sensor type does not support placeholders to provide the name of the target file. Because log files often have the date of creation in their name, the File sensor might not be perfectly suitable in your scenario.

To monitor log files with date in the name, for example, you can use a custom sensor with a PowerShell script that allows placeholders for the files that you want to monitor. We provide such a sample script below. You can just use the script and adjust the parameters to your scenario. The script also gives you an idea about how to use placeholders for monitoring files in other scenarios.

For this purpose you need an EXE/Script Advanced sensor. This sensor can execute the sample script and shows the following data:

  • Number of files that match the pattern of the given file name with placeholders
  • Age of oldest and newest file matching the name pattern
  • Size of the newest file matching the name pattern
  • Total size of files matching the name pattern

See below for the sample script and how to use it.

How to Use the PowerShell Script

  1. Open a text editor.
  2. Copy the source code from below and paste it into the editor.
  3. Adjust the default values for $path and $include to your scenario. The script as provided below looks for .txt-files in the \temp folder of the target machine. You can also control the script execution with the Parameters setting of the sensor.
  4. Save the file with the extension .ps1, for example, “logfileStats.ps1.”
  5. Copy this file into your PRTG installation folder, subfolder \Custom Sensors\EXEXML, on the system with the probe from which you want to monitor your files.
  6. In PRTG add an EXE/Script Advanced sensor to the target device.
    1. Choose logfileStats.ps1 from the list of scripts.
    2. Provide the Parameters that you want to use to execute the script. For the sample script, these are the path to the target files and the file name pattern include. For example, to monitor log files of an Apache webserver that have the date right before the file extension, you can provide the following parameter which overrides the defaults: -path \\<unc-path to share>\apache-log\*\ -include Webserver.log-*
    3. Adjust all other sensor settings to your needs.
    4. Click Continue to add the sensor. The sensor will show the retrieved data in the channels Files matching pattern, Oldest File, Newest File, Newest File Size, and Size (see the bullet points above for detailed descriptions).

Note: We do not provide official support for custom sensors. Of course, you are free to adjust the script according to your needs!


Script

Param(
    [string]$path="C:\temp",
    [string]$include= "*.txt"
    )
 
$result = ""
$size = 0
# Get the list of all files
$files =  Get-ChildItem -Path $path -include $include -Recurse | Sort-Object LastWriteTime
$count = $files.count
if ($count -gt 0)
{
    $newestfilesize = $files[-1].length
    $oldestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[0].LastWriteTime).TotalDays).Replace(',','.')
    $newestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[-1].LastWriteTime).TotalDays).Replace(',','.')
    foreach ($file in $files) { 
        $size += $file.length
        }
	
 

    $result += @" 
	<result>
		<value>$count</value>
		<unit>count</unit>
		<channel>Number of $($include) Files</channel>
	</result>
	<result>
		<value>$oldestfile</value>
		<unit>custom</unit>
		<CustomUnit>Days</CustomUnit>
		<float>1</float>
		<channel>Oldest File Age</channel>
	</result>
	<result>
		<value>$newestfile</value>
		<unit>custom</unit>
		<CustomUnit>Days</CustomUnit>
		<float>1</float>
		<channel>Newest File Age</channel>
	</result>
	<result>
		<value>$newestfilesize</value>
		<unit>BytesFile</unit>
		<volumeSize>Byte</volumeSize>
		<float>0</float>
		<channel>Newest File Size</channel>
	</result>
	<result>
		<value>$size</value>
		<unit>BytesFile</unit>
		<volumeSize>Byte</volumeSize>
		<channel>Total File Size</channel>
	</result>
	<text>
	OK
	</text>
"@
} else {
    $result += @" 
    <error>1</error>
	<text>
	No file found matching the filter-parameter "$include" at path "$path" 
	</text>
"@
 
}
write-host @"
<?xml version=1.0 encoding=UTF-8 ?>
<prtg>
$result
</prtg>
"@

Created on Jan 21, 2016 1:25:12 PM by  Gerald Schoch [Paessler Support]

Last change on Sep 18, 2018 11:17:54 AM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Hello,

I am currently using the script above, but unfortunately i am getting a 0 Byte value returned for the newest file size. Hopefully you can tell me what i am missing, i do not see the error.

All other values are returned OK, number of files, total file size, ages, even for the newest file the age is returned.

Kind regards,

Kevin

Screenshot: screenshot

Parameters PRTG: -path \\dehze01-wsv622\d$\_Qlikview\Production\Data\QVD\IVY\*.QVD -include *.QVD

PS1 script:

Param(
    [string]$path="d$\_Qlikview\Production\Data\QVD\IVY\*.QVD",
    [string]$include= "*.QVD"
    )
 
$result = ""
$size = 0
# Get the list of all files
$files =  Get-ChildItem -Path $path -include $include -Recurse
$count = $files.count
if ($count -gt 0)
{
    $oldestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[0].LastWriteTime).TotalDays).Replace(',','.')
    $newestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[-1].LastWriteTime).TotalDays).Replace(',','.')
    foreach ($file in $files) { 
        $size += $file.length
        }
 
    $result += @" 
	<result>
		<value>$count</value>
		<unit>count</unit>
		<channel>Number of QVD Files</channel>
	</result>
	<result>
		<value>$oldestfile</value>
		<unit>custom</unit>
		<CustomUnit>Days</CustomUnit>
		<float>1</float>
		<channel>Oldest File Age</channel>
	</result>
	<result>
		<value>$newestfile</value>
		<unit>custom</unit>
		<CustomUnit>Days</CustomUnit>
		<float>1</float>
		<channel>Newest File Age</channel>
	</result>
	<result>
		<value>$newestfilesize</value>
		<unit>BytesFile</unit>
		<volumeSize>Byte</volumeSize>
		<float>0</float>
		<channel>Newest File Size</channel>
	</result>
	<result>
		<value>$size</value>
		<unit>BytesFile</unit>
		<volumeSize>Byte</volumeSize>
		<channel>Total File Size</channel>
	</result>
	<text>
	OK
	</text>
"@
} else {
    $result += @" 
    <error>1</error>
	<text>
	No file found matching the filter-parameter "$include" at path "$path" 
	</text>
"@
 
}
write-host @"
<?xml version=1.0 encoding=UTF-8 ?>
<prtg>
$result
</prtg>
"@

Created on Jul 12, 2016 10:08:29 AM by  Kevin Bakker (0) 2

Last change on Jul 14, 2016 8:04:43 AM by  Torsten Lindner [Paessler Support]



Votes:

0

Your Vote:

Up

Down

When you execute it manually, what output do you get there?

Created on Jul 13, 2016 12:38:12 PM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Hello,

I am pretty sure there's something in the script which causes this. My knowledge doesn't allow me to fix it, i just copied the above and adjusted the custom options within the script.

Hopefully the creator of the script can give some more detailed information ? perhaps this script doesn't work at all. Still hoping the solution is out there, would hate to go around PRTG making scripts that generate txt output to monitor with PRTG, i liked this script because it just runs from PRTG.

Many thanks in advanced !

Kind regards,

Kevin

Created on Aug 18, 2016 7:42:28 AM by  Kevin Bakker (0) 2



Votes:

0

Your Vote:

Up

Down

I'll check out the script and let you know what I find out...

Created on Aug 18, 2016 8:41:50 AM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Turns out that the script had a few bugs:

  • $newestfilesize was never defined
  • newest and oldest file were not correctly sorted (order was alphabetical instead of by LastWriteTime)

Updated version can be found in the original answer :)

Created on Aug 19, 2016 9:41:23 AM by  Stephan Linke [Paessler Support]

Last change on Aug 19, 2016 9:41:47 AM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Thank you very, very much ! This is exactly what we where looking for.

Thanks again !

Created on Aug 22, 2016 1:24:19 PM by  Kevin Bakker (0) 2



Votes:

0

Your Vote:

Up

Down

I have problems with the script or sensor.

I am getting this : XML: Structural error in xml file, 1 open items. -- JSON: The returned json does not match the expected structure (Invalid JSON.). (code: PE231)

I have a DFS file location, which is actually a samba share. I have tried this script first on the machine but thats a unix machine and guessing a ps1 wont work on that.

so I picked another server which has acces to that file share.

The parameters :
ourdomainname.local\dfs\TriathlonFiles\locus\prod\tohost

script

Param(
    [string]$path="\\oosterberg.local\dfs\TriathlonFiles\locus\prod\tohost",
    [string]$include= "*.dat"
    )
 
$result = ""
$size = 0
# Get the list of all files
$files =  Get-ChildItem -Path $path -include $include -Recurse | Sort-Object LastWriteTime
$count = $files.count
$newestfilesize = $files[-1].length
if ($count -gt 0)
{
    $oldestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[0].LastWriteTime).TotalDays).Replace(',','.')
    $newestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[-1].LastWriteTime).TotalDays).Replace(',','.')
    foreach ($file in $files) { 
        $size += $file.length
        }
	
 

    $result += @" 
	<result>
		<value>$count</value>
		<unit>count</unit>
		<channel>Number of $($include) Files</channel>
	</result>
	<result>
		<value>$oldestfile</value>
		<unit>custom</unit>
		<CustomUnit>Days</CustomUnit>
		<float>1</float>
		<channel>Oldest File Age</channel>
	</result>
	<result>
		<value>$newestfile</value>
		<unit>custom</unit>
		<CustomUnit>Days</CustomUnit>
		<float>1</float>
		<channel>Newest File Age</channel>
	</result>
	<result>
		<value>$newestfilesize</value>
		<unit>BytesFile</unit>
		<volumeSize>Byte</volumeSize>
		<float>0</float>
		<channel>Newest File Size</channel>
	</result>
	<result>
		<value>$size</value>
		<unit>BytesFile</unit>
		<volumeSize>Byte</volumeSize>
		<channel>Total File Size</channel>
	</result>
	<text>
	OK
	</text>
"@
} else {
    $result += @" 
    <error>1</error>
	<text>
	No file found matching the filter-parameter "$include" at path "$path" 
	</text>
"@
 
}
write-host @"
<?xml version=1.0 encoding=UTF-8 ?>
<prtg>
$result
</prtg>
"@

Created on Aug 26, 2016 6:18:46 AM by  rnijland (0) 1



Votes:

0

Your Vote:

Up

Down

Did you execute Set-ExecutionPolicy RemoteSigned in a administrative 32bit PowerShell already? Does the script work in a normal powershell?

Created on Aug 26, 2016 7:09:40 AM by  Stephan Linke [Paessler Support]

Last change on Aug 26, 2016 7:10:14 AM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

The Get-ExecutionPolicy gives unrestricted back.

No it wont work in a normal powershell, it gives this:

PS C:\> Get-executionpolicy
Unrestricted
PS C:\> .\dat-files
Unable to index into an object of type System.IO.FileInfo.
At C:\DAT-Files.ps1:11 char:26
+ $newestfilesize = $files[ <<<< -1].length
    + CategoryInfo          : InvalidOperation: (-1:Int32) [], RuntimeException
    + FullyQualifiedErrorId : CannotIndex

<?xml version=1.0 encoding=UTF-8 ?>
<prtg>
    <error>1</error>
        <text>
        No file found matching the filter-parameter "*.dat" at path "\\oosterberg.local\dfs\TriathlonFiles\locus\prod\to
host"
        </text>
</prtg>
PS C:\>

I tried the example script with a C:\temp path and txt file in it, and then the sensor work. I think its something with the pad, though the path I am using is correct

Created on Aug 26, 2016 7:34:13 AM by  rnijland (0) 1



Votes:

0

Your Vote:

Up

Down

It's quite possible that PRTG can't access the path properly which would explain the fileinfo exception - it simply can't list any files on there from what it seems.

Created on Aug 26, 2016 7:45:04 AM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Yes, I'm trying to get a point with it. Its a share which I can acces from the probe. Its also a share on a unix machine. The root of machine has other credentials to acces but able to acces the shares with windows credentials as samba does the trick.

Powershell can user unc paths. I dont see the problem actually, I created the sensor on the probe device.

I tried a windows share (windows machine) with a doc file, locally on the probe with powershel the scripts works, when I create a sensor on the probe and it wont work.

Created on Aug 26, 2016 7:59:41 AM by  rnijland (0) 1



Votes:

0

Your Vote:

Up

Down

Can you execute

Get-ChildItem -Path "\\oosterberg.local\dfs\TriathlonFiles\locus\prod\tohost"

...in a powershell just fine? On the actual probe? Do you run the script on an actual remote probe? Did you set the executionpolicy on the remote probe itself as well?

Created on Aug 26, 2016 8:24:54 AM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Hi, after some time testing this i stumbled across the following:

  • script runs fine on prtg-server
  • script runs fine on my Window 7 desktop
  • script runs fine the the server/share to be monitored

I want to check, if filenames with text *a9r* are existent in a directory. Existence is bad, absence is good.

Sample output, five files found:

<?xml version=1.0 encoding=UTF-8 ?> <prtg> <result> <value>5</value> <unit>count</unit> <channel>Number of *a9r* Files**</channel> </result> <result> <value>7,01</value> <unit>custom</unit> <CustomUnit>Days</CustomUnit> <float>1</float> <channel>Oldest File Age</channel> </result> <result> <value>0,00</value> <unit>custom</unit> <CustomUnit>Days</CustomUnit> <float>1</float> <channel>Newest File Age</channel> </result> <result> <value>1673</value> <unit>BytesFile</unit> <volumeSize>Byte</volumeSize> <float>0</float> <channel>Newest File Size</channel> </result> <result> <value>1673</value> <unit>BytesFile</unit> <volumeSize>Byte</volumeSize> <channel>Total File Size</channel> </result> <text> OK

Putting it to work in PRTG in Custom Sensors\EXEXML results in No file found matching the filter-parameter "*a9r*" at path SERVER\C$\temp\*. But there are five files present. What else can i try?

Created on Dec 14, 2017 1:34:20 PM by  mbn (0)



Votes:

0

Your Vote:

Up

Down

What path are you actually using? If you want to access the administrative C:\ share,
you'll need C$\temp\ instead of \ \<hostname>\C$\temp


Kind regards,
Stephan Linke, Tech Support Team

Created on Dec 18, 2017 8:30:42 AM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Thank you for the answer.

Update: The monitor is working now, it simply failed because of this setting:

Sicherheitskontext
wrong: Sicherheitskontext des Probe-Dienstes verwenden
right: Die Zugangsdaten für Windows des übergeordneten Geräts verwenden

Path in script (this works, C$\temp\ does not work). The script is executed on PRTG-Server so it seems logic to me to add the SERVER name.

Param( [string]$path='\ \SERVER\C$\temp\*', [string]$include= '*a9r*' )

The only thing i am not able to do is to teach him, that absence of a9r is good, presence of a9r is bad. It still needs one a9r in C:\temp file to show green sensor value. Zero a9r-file results in sensor getting grey and red. Any hint on this?

Created on Dec 18, 2017 12:47:28 PM by  mbn (0)



Votes:

0

Your Vote:

Up

Down

Is the script actually returning 0 or an empty string as result when no a9r files are present?


Kind regards,
Stephan Linke, Tech Support Team

Created on Dec 18, 2017 8:08:09 PM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Zero a9r files:

Yellow (W) Sensor A9R
No file found matching the filter-parameter "*a9r*" at path "\ \SERVER\C$\temp\*" .... i guess this is the result of the else-clause in the script from Gerald Schoch

<error>1</error>
	<text>
	No file found matching the filter-parameter "$include" at path "$path" 
	</text>

"No data" in the channel fields of sensor.

After 600 seconds: Red A9R: No file found matching the filter-parameter "*a9r*" at path "
ctps01\C$\temp\*"

But running the powershell-script with zero a9r in directory results in

Cannot index into a null array. At D:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML\A9R-check.ps1:11 char:1 + $newestfilesize = $files[-1].length + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : NullArray

Created on Dec 19, 2017 12:37:13 PM by  mbn (0)



Votes:

0

Your Vote:

Up

Down

Ah, well you need to capture the error correctly (i.e. output 0 files). Try/Catch is your friend here :)


Kind regards,
Stephan Linke, Tech Support Team

Created on Dec 19, 2017 1:06:08 PM by  Stephan Linke [Paessler Support]



Votes:

1

Your Vote:

Up

Down

For me, there were two bugs in this script:

1: Fails, if only ONE file found

With only ONE file found, this command does not return an array but a single item!

So this IF statement will fail because single item doesn't have a count property:

$count = $files.count
if ($count -gt 0)

Therefore, this line $files = Get-ChildItem -Path $path -include $include -Recurse | Sort-Object LastWriteTime

has to be corrected with a surrounding @( ) to always return an array: $files = @(Get-ChildItem -Path $path -include $include -Recurse | Sort-Object LastWriteTime)

See Technet Forum: GetChildItem count returns null if there is one file in a folder

2: Move $newestfilesize infto IF

$count = $files.count
$newestfilesize = $files[-1].length
if ($count -gt 0)
{

should be corrected to

$count = $files.count
if ($count -gt 0)
{
   $newestfilesize = $files[-1].length

to prevent errors on an empty array

Created on Sep 18, 2018 10:25:33 AM by  ITSE (10)



Votes:

0

Your Vote:

Up

Down

Hi ITSE,

Thanks, I've updated the script accordingly. Much appreciated!


Kind regards,
Stephan Linke, Tech Support Team

Created on Sep 18, 2018 11:18:23 AM by  Stephan Linke [Paessler Support]



Please log in or register to enter your reply.


Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.