Skip to main content
Version: 2026.10

ScansorSensors

C# (.NET Framework 4.8) solution with PRTG custom sensors (EXE/advanced sensors). One project per sensor folder, all in ScansorSensors.sln.

Conventions​

  • Each sensor folder contains: <Name>.cs, <Name>.csproj, <Name>.json (parameters), desc.json, <slug>.md (documentation), docs/*.html (one page per parameter), optional *.ovl (PRTG value lookups).
  • Base classes from the NuGet package Itesys (Itesys.Models): SensorExe (generic) and RFCSensorExe (SAP RFC, provides RFCConnection).
    • Parameters["..."], JSONResult.AddChannel(name, value, unit:, customUnit:, valueLookup:, limitMaxError:, limitMaxWarning:, ...), JSONResult.SetText(...), Error(msg, code) + Abort(), Trace(...).
    • Each sensor has a unique protected override int SensorCode.
    • Main pattern: new Sensor(args); sensor.Execute(); Console.OutputEncoding = UTF8; Console.Write(sensor.PrintResult());
  • RFC helpers (RFCConnection):
    • Table read: SetTable / SetFields / SetOptions + ExecuteDatabaseConnection() → List<Dictionary<string,string>>.
    • FM call: SetFunction(name, Dictionary<string, dynamic>) + Execute() → IRfcFunction. Limitation (checked via IL of Itesys 2026.8.0.1): it only sets scalars and appends table rows with a single field. For structures or range tables (SIGN/OPTION/LOW) use NCo directly on the framework destination: RfcDestinationManager.GetDestination("SAP") → Repository.CreateFunction(...) → Invoke(destination).
    • Projects using NCo types need the sapnco / sapnco_utils references (copy from SAP_WorkProcess_Monitor.csproj).
  • Build (no Python on the dev machine; use PowerShell):
    $vs = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" | Select-Object -First 1
    & $vs "<Folder>\<Name>.csproj" /restore /p:Configuration=Release /p:Platform=x64 /v:minimal /nologo
  • Style: tabs/indentation as in the surrounding file, comments sparse, English.

Work in progress​

SAP_BusinessObjects_MonitorV2 (branch TASK-1263)​

Replacement for SAP_BusinessObjects_Monitor (old one does not work with BI 2025). SensorCode 106. Uses the BI RESTful web services (/biprws), base URL Protocol://Host:Port.

  • Logon: POST /biprws/logon/long with XML <attrs xmlns="http://www.sap.com/rws/bip"> (userName = SAPUsername, password = SAPPassword, auth = AuthMethod). Token from header X-SAP-LogonToken (fallback: attr logonToken in body). Token is sent quoted in X-SAP-LogonToken. Logoff POST /biprws/logoff in finally.
  • Paged JSON lists (pagesize 50) follow next.__deferred.uri; only path+query are used because the API returns its internal host (e.g. 10.10.16.9:8443).
  • Channels: Login Status (lookup itesys.sapbusinessobjectsmonitorv2.loginstatus: 0 OK, 1 not reachable, 2 logon rejected; on failure no other channels), Login Responsetime (ms), one channel per enabled server (lookup itesys.sapbusinessobjectsmonitorv2.serverstatus: 0 Running, 1 running with errors, 2 not running), Servers not running (error > 0), Servers running with errors (warning > 0), Servers disabled, Active User Sessions, System Sessions.
  • Data sources (verified against a BI 2025 system):
    • GET /biprws/bionbi/server/list → entries[] with title, kind, status_type ("Running"/"Stopped"), disabled ("Enabled"/"Disabled").
    • GET /biprws/infostore/41/children (Logon Sessions) → entries type: Connection, name = user; "System Account" = internal sessions; the sensor's own session is subtracted.
  • InfoStore findings: detail views (/biprws/infostore/<id>) only return cuid, name, description, id, type – no status, timestamps or expiry. Folder ids: 24 License Keys, 41 Logon Sessions, 59 Enterprise Nodes, 62 Server Intelligence, 64 Alert Notifications (~850 entries, sorted by name, e.g. "Consolidated Health Watch Caution Event"), 16 Servers.
  • Open:
    • Test POST /biprws/v1/cmsquery (or /biprws/infostore/cmsquery) on BI 2025. If it works: license expiry, node/SIA status, failed/running instances, recent Danger alerts become possible. Not tested yet.
    • SAP_BusinessObjects_MonitorV2.json: RequiredParameters still lists OSUsername/OSPassword, code uses SAPUsername/SAPPassword; default Protocol=http vs default Port=8443 (likely https).
    • desc.json and docs/*.html still describe the old sensor (CMSQueryPort, HTTPPort, Username, Password). .md is updated.
    • Not yet run against a real system.

SAP_AuditLog_Monitor​

New sensor (copied from SAP_ApplicationLog_Monitor), reads the Security Audit Log via FM RSAU_API_GET_LOG_DATA (function group RSAU_LOG, SAP_BASIS ≥ 7.50, remote-enabled). SensorCode 107.

  • FM interface: IS_INTERVAL (fields DAT_FROM, TIM_FROM, DAT_TO, TIM_TO), range tables IT_R_MSG, IT_R_MANDT, IT_R_USER, IT_R_TCD, IT_R_REPS, IT_R_INSTANCE; outputs ET_LOG, ET_LOG_UTC, ET_FSTAT, ET_RETURN.
  • Parameters (SAP_AuditLog_Monitor.json): Minutes (max 1440) → IS_INTERVAL; SAPClient → IT_R_MANDT; Events → IT_R_MSG, Users → IT_R_USER, Tcodes → IT_R_TCD, Programs → IT_R_REPS, Instances → IT_R_INSTANCE. * = no filter, value with * → CP, otherwise EQ.
  • Channel: "Audit Log Events" (row count of ET_LOG); sensor text lists distinct "event (user)". Error codes 051/052 (Minutes), 054 (ABAP exception), 055 (other), 056 (ET_RETURN type E/A), 057 (preset/FILE: file not found), 058 (invalid preset line).
  • Presets: parameter Preset (default NONE = no preset, because the framework rejects empty parameters) → SAP_AuditLog_Monitor\<name>[.preset] with key=value lines (Minutes, Events, Users, Tcodes, Programs, Instances; #/// comments). A PRTG value that differs from its default (*, 60) overrides the preset. Each filter also accepts FILE:<file> (one value per line). Shipped: Failed_Logons, Emergency_Users, User_Admin, Audit_Config_Changes (event IDs from memory, verify in SM19/RSAU_CONFIG). Copied via its own step in azure-pipelines.yml.
  • Open:
    • ET_LOG column names unconfirmed – candidates in EventFields / UserFields at the top of the class; get the real names from SE37.
    • ET_RETURN assumed BAPIRET2-like (TYPE, MESSAGE).
    • Time window uses the probe's local time; consider /SOMO/GET_TIMEZONE offset like SAP_Dump_MonitorV2.
    • Not yet run against a real system (also needs the Scansor runtime / sensors.db, so no local runs).