lordmilko / PrtgAPI

C#/PowerShell interface for PRTG Network Monitor
MIT License
301 stars 37 forks source link

Get-SensorHistory : Input string was not in a correct format. #111

Closed patuzjadeitu closed 4 years ago

patuzjadeitu commented 4 years ago

Describe the bug Get-SensorHistory crashes upon recieving input from PRTG on some ids. This terminates the cmdlet even with $ErrorActionPreference = 'SilentlyContinue'

Steps to reproduce Crashes always on the same id: VERBOSE: Get-SensorHistory: Synchronously executing request https://myserver/api/historicdata.xml?id=57531&edate=2019-09-30-00-00-00&sdate=2019-09-29-00-00-00&avg=0&sortby=-datetime&count=500&start=500&username=myusername&passhash=mypass

#Get-Sensor -Type ping |  Get-SensorHistory -StartDate '2019-09-30' -EndDate '2019-09-29' -Verbose 

Additional context Value that I suspect is the offender: Get-SensorHistory expects type int on <value channel="Maximum" also <value channel="Minimum" also suspicable to the same error? Item on which Get-SensorHistory crashes:

<item>
<datetime>29.09.2019 23:01:52</datetime>
<datetime_raw>43737.8763076736</datetime_raw>
<value channel="Ping Time" channelid="0">440 msec</value>
<value_raw channel="Ping Time" channelid="0">439.8000</value_raw>
<value channel="Minimum" channelid="1">4 msec</value>
<value_raw channel="Minimum" channelid="1">4.0000</value_raw>
<value channel="Maximum" channelid="2">1.128 msec</value>
<value_raw channel="Maximum" channelid="2">1128.0000</value_raw>
<value channel="Packet Loss" channelid="3">0 %</value>
<value_raw channel="Packet Loss" channelid="3">0.0000</value_raw>
<coverage>100 %</coverage>
<coverage_raw>0000010000</coverage_raw>
</item>
lordmilko commented 4 years ago

Hi @greenstonepatu,

Can you please provide all the error message text that is displayed when this crashes?

In addition, after you reproduce it again can you do $error[0].Exception.StackTrace and provide the stack trace details

patuzjadeitu commented 4 years ago

Hi @lordmilko

Sure, there it is:

At line:1 char:1
+ Get-SensorHistory -Id 57531 -StartDate '2019-09-30' -EndDate '2019-09 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [Get-SensorHistory], FormatException
+ FullyQualifiedErrorId : System.FormatException,PrtgAPI.PowerShell.Cmdlets.GetSensorHistory
> $error[0].Exception.StackTrace
   at System.Number.ParseDouble(ReadOnlySpan`1 value, NumberStyles options, NumberFormatInfo numfmt)
   at System.Convert.ToDouble(String value)
   at PrtgAPI.PowerShell.SensorHistoryFormatter.GetChannelValue(ChannelHistoryRecord channel)
   at PrtgAPI.PowerShell.SensorHistoryFormatter.CreateObject(SensorHistoryRecord date)
   at PrtgAPI.PowerShell.SensorHistoryFormatter.PrepareObject(SensorHistoryRecord data, Boolean isNew)
   at PrtgAPI.PowerShell.SensorHistoryFormatter.Init(List`1 firstResponse)+MoveNext()
   at PrtgAPI.PowerShell.SensorHistoryFormatter.Format(IEnumerable`1 response, Boolean lazy, Nullable`1 count)+MoveNext()
   at PrtgAPI.PowerShell.Base.PrtgProgressCmdlet.WriteList[T](IEnumerable`1 sendToPipeline)
   at PrtgAPI.PowerShell.Cmdlets.GetSensorHistory.ProcessRecordEx()
   at PrtgAPI.PowerShell.Base.PrtgCmdlet.ExecuteWithCoreState(Action action)
   at PrtgAPI.PowerShell.Base.PrtgCmdlet.ProcessRecord()
   at System.Management.Automation.CommandProcessor.ProcessRecord()

Best regards

lordmilko commented 4 years ago

Thanks @greenstonepatu,

I was unable to reproduce the issue faking a request with the XML specified in your original post.

Can you please copy and paste the URL from -Verbose into your browser and provide the complete historicdata.xml file for the affected sensor?

In addition, are you able to advise what version of PrtgAPI you're using? Simply run gmo PrtgAPI in a PowerShell prompt where you've executed at least one PrtgAPI command

patuzjadeitu commented 4 years ago

Hi @lordmilko

Github doesn't support attaching xml, so here's a link to the historicdata file: historicdata.xml I'm using the latest version of your API.

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Binary     0.9.9      PrtgAPI                             {Add-Device, Add-Group, Add-NotificationTrigger, Add-Sensor…}
Get-SensorHistory -Id 57531 -StartDate '2019-09-29 23:03' -EndDate '2019-09-29 23:00' -Verbose
VERBOSE: Get-SensorHistory: Synchronously executing request https://myserver

/api/historicdata.xml?id=57531&edate=2019-09-29-23-03-00&sdate=2019-09-29-23-00-00&avg=0&sortby=-datetime&count=0&username=myusername&passhash=mypass
VERBOSE: Get-SensorHistory: Preparing to serially stream objects
VERBOSE: Get-SensorHistory: Synchronously executing request https://myserver/api/historicdata.xml?id=57531&edate=2019-09-29-23-03-00&sdate=2019-09-29-23-00-00&avg=0&sortby=-datetime&count=500&username=myusername&passhash=mypass

DateTime            SensorId PingTime(msec) Minimum(msec) Maximum(msec) PacketLoss(%) Coverage(%)
--------            -------- -------------- ------------- ------------- ------------- -----------
29.09.2019 23:02:50 57531    5              4             5             0             100
29.09.2019 23:02:20 57531    4              4             5             0             100
Get-SensorHistory : Input string was not in a correct format.
At line:1 char:1
+ Get-SensorHistory -Id 57531 -StartDate '2019-09-29 23:03' -EndDate '2 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [Get-SensorHistory], FormatException
+ FullyQualifiedErrorId : System.FormatException,PrtgAPI.PowerShell.Cmdlets.GetSensorHistory

$error[0].Exception.StackTrace
   at System.Number.ParseDouble(ReadOnlySpan`1 value, NumberStyles options, NumberFormatInfo numfmt)
   at System.Convert.ToDouble(String value)
   at PrtgAPI.PowerShell.SensorHistoryFormatter.GetChannelValue(ChannelHistoryRecord channel)
   at PrtgAPI.PowerShell.SensorHistoryFormatter.CreateObject(SensorHistoryRecord date)
   at PrtgAPI.PowerShell.SensorHistoryFormatter.Init(List`1 firstResponse)+MoveNext()
   at PrtgAPI.PowerShell.SensorHistoryFormatter.Format(IEnumerable`1 response, Boolean lazy, Nullable`1 count)+MoveNext()
   at PrtgAPI.PowerShell.Base.PrtgProgressCmdlet.WriteList[T](IEnumerable`1 sendToPipeline)
   at PrtgAPI.PowerShell.Cmdlets.GetSensorHistory.ProcessRecordEx()
   at PrtgAPI.PowerShell.Base.PrtgCmdlet.ExecuteWithCoreState(Action action)
   at PrtgAPI.PowerShell.Base.PrtgCmdlet.ProcessRecord()
   at System.Management.Automation.CommandProcessor.ProcessRecord()

Best regards

lordmilko commented 4 years ago

This works fine on my computer, so this indicates there is something specific to your environment that is different to mine

  1. What operating system are you running
  2. It looks like you're using PowerShell Core; are you able to advise what the PSVersion returned from $PSVersionTable is?
  3. What is culture is returned from Get-Culture?
  4. What is the output of the command 1.1
patuzjadeitu commented 4 years ago

It was indeed fault of my local settings. I had comma set as a decimal symbol in Region > Customize Format settings. Changing it to period resolved my issue. Many thanks for the support and for the great work that you are doing @lordmilko !

  1. What operating system are you running Windows 10(Build 10240)
    1. It looks like you're using PowerShell Core; are you able to advise what the PSVersion returned from $PSVersionTable is?
      Name                           Value
      ----                           -----
      PSVersion                      6.2.3
      PSEdition                      Core
      GitCommitId                    6.2.3
      OS                             Microsoft Windows 10.0.10240
      Platform                       Win32NT
      PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
      PSRemotingProtocolVersion      2.3
      SerializationVersion           1.1.0.1
      WSManStackVersion              3.0
    2. What is culture is returned from Get-Culture?
      LCID             Name             DisplayName
      ----             ----             -----------
      1045             pl-PL            Polish (Poland)
    3. What is the output of the command 1.1 it was... 1,1 ;-)

Best regards

lordmilko commented 4 years ago

Thanks @greenstonepatu!

I had tried replicating this issue on a German PRTG server which uses a comma as a decimal separator, however I was unable to reproduce the issue; what I did notice however was that the decimal number 1.128 was being transformed into 1128. That is definitely a bug whether it results in a crash or not.

By default, Get-SensorHistory extracts its values based on the DisplayValue of each channel; when your PRTG language is something like German, I imagine this value would use a comma instead of a period; that persons computer would likely also be running a German version of Windows, so there would be no discrepancy between the number formats and thus would be parsed correctly.

In order to guarantee the value can be parsed regardless of the users number format, I will perform an audit of all places ToDouble is called in PrtgAPI, replace any commas with periods and force the use of InvariantCulture where appropriate.

In the meantime, you can either use a period-based number format as you have done, or execute Get-SensorHistory with the -Raw parameter; this should bypass these sorts of shenanigans for now without forcing you to use a "foreign" number format

In order to assist with these sorts of investigations in the future I think I will add a new command you can use to gather all the key information needed to begin an investigation in one go

Thanks for your help in identifying this issue!

Regards, lordmilko

patuzjadeitu commented 4 years ago

@lordmilko

Yes, the PRTG servers are German, but I'm using English version of Windows 10. Again many thanks!

lordmilko commented 4 years ago

Hi @greenstonepatu,

Please be advised PrtgAPI 0.9.10 has been released, which includes a fix for this issue. To update to the latest version of PrtgAPI run the command

Update-Module PrtgAPI

and then close and reopen PowerShell. Of course, in your case you have already worked around the issue, so potentially you may be happy to leave things as is

Regards, lordmilko