SAP API Management Syslog

SAP API Management Syslog

Overview

The SAP API Management Syslog Input enables your PowerConnect Cloud deployment to ingest syslog-formatted logs emitted from SAP API Management, which is based on Google’s Apigee API Gateway. Logs are sent via a custom policy in the API proxy flow using the built-in Message Logging policy that formats and emits log messages to PowerConnect Cloud.

Once received, these logs can be transformed and routed to downstream observability systems or retained for audit and troubleshooting purposes.

Data Collected

The data collected depends on the configuration of your SAP API proxy and the logging policy in use.

Typical fields include:

  • Timestamp: When the log was emitted

  • Client IP: Source of the incoming API call

  • API Proxy Name: The proxy that handled the request

  • Request URI / Path

  • HTTP Method

  • Status Code

  • Latency / Response Time

  • Environment / Organization

  • Custom Headers or Variables: You may include any context-specific variables (e.g., user ID, token ID, etc.)

  • Error Details: In the event of policy failures or backend errors

Logs should be emitted in structured JSON format wrapped inside the syslog message. PowerConnect Cloud can be configured to extract and normalize this JSON data into log events.

Use Cases

  • Audit Logging: Capture and retain all API calls and responses for compliance and audit purposes.

  • Error Monitoring: Detect and route failed requests or policy violations to alerting systems or dashboards.

  • Performance Metrics: Derive metrics such as request latency, error rate, and traffic volume per API endpoint or client.

  • Threat Detection: Analyze incoming requests for anomalies or abuse patterns (e.g., rate-limiting violations, malformed tokens).

  • Customer Usage Insights: Track usage patterns per client or application to inform service design or licensing decisions.

Status

Available

Configuration

To forward logs from SAP API Management to PowerConnect Cloud, you must configure a Message Logging policy within each API proxy that you wish to monitor. This involves defining a syslog endpoint, formatting the log message, and attaching the policy to the appropriate flow.

Adding an API-M Syslog Input to PowerConnect Cloud

  • Login to the PowerConnect Cloud web UI

  • Click on the Inputs link in the menu bar

  • Click the + button to add a new Input

  • Select API-M

    image-20250604-043151.png
  • Select api-m-syslog

    image-20250604-043223.png
  • Fill out the configuration details of the Syslog listener where:

    • Port to listen on = the tcp port for listener, this should be above 1024

    • Batch size = number of messages to batch together before processing

    • Flush batch after this many milliseconds = number of milliseconds to wait before batch is flushed if the batch size is not reached

    image-20250604-043340.png
  • Click the Transforms tab

  • Add a new transform for the field message and choose the Parse field as JSON function

    image-20250604-043906.png
  • This will parse the syslog json object as part of the message field and make its fields searchable in the target platform

  • Click Save

  • The API-M Syslog listener should now be started and listening on the tcp port specified in the configuration

Configuring API Management

Prerequisites

  • A running PowerConnect Cloud syslog receiver over TCP

  • IP address and port of your PowerConnect Cloud syslog endpoint

  • Connectivity from SAP API Management to PowerConnect Cloud syslog TCP port

  • Access to the SAP API Management Portal UI and appropriate permissions to modify the APIs

Steps

  • Login to the API Portal

  • Click Develop in the menu on the left

  • In the APIs table click on the API you wish to monitor

  • Click Policies in the top right

    image-20250603-222632.png
  • Click Edit

    image-20250604-003108.png
  • Under Scripts click Add

  • Select Create then name the script capture_request and click Add

    image-20250604-004357.png
  • Use the following example code and modify it to collect the request attributes you require:

    // Capture request information var httpScheme = context.getVariable("client.scheme"); var httpTarget = context.getVariable("request.path"); var hostName = context.getVariable("request.header.host"); var url = httpScheme + "://" + hostName + httpTarget; var requestInfo = { "apiproxy.name": context.getVariable("apiproxy.name"), "developer": context.getVariable("developer.app.name"), "headers": {}, "method": context.getVariable("request.verb"), "proxy.basepath": context.getVariable("proxy.basepath"), "url": url, "user-agent": context.getVariable("request.header.user-agent") };
  • Click Update to save the script

  • Under Scripts click Add

  • Select Create then name the script capture_response and click Add

    image-20250604-004906.png
  • Use the following example code and modify it to collect the response attributes you require. In the example all response headers are collected and joined with the original request data. A json output is produced:

    // Retrieve the previously captured request information var requestInfo = JSON.parse(context.getVariable("custom.requestInfo")); // Capture response details var responseInfo = { "headers": {}, // Placeholder for response headers "reason": context.getVariable("response.reason.phrase"), "status": context.getVariable("response.status.code") }; // Check if a fault occurred var isFault = context.getVariable("fault.name") !== null; // Dynamically collect all response headers (handling Set object) var responseHeaderNames = context.getVariable("response.headers.names"); if (responseHeaderNames) { var headerSet = responseHeaderNames.toArray(); // Convert Set to Array headerSet.forEach(function(header) { var headerValue = context.getVariable("response.header." + header); responseInfo.headers[header] = headerValue; }); } if (isFault) { responseInfo.body = context.getVariable("response.content"); // Capture the response body in case of a fault } var start_time = context.getVariable("client.received.start.timestamp"); var end_time = context.getVariable("system.timestamp"); var duration = end_time - start_time; // Build the final JSON structure var output = { "ended_at": end_time, "error": { "error.message": context.getVariable("error.message") || "", "error.reason.phrase": context.getVariable("error.reason.phrase") || "", "error.status.code": context.getVariable("error.status.code") || "" }, "request": requestInfo, "response": responseInfo, "service": { "environment": "EnvironmentInfo {name = " + context.getVariable("environment.name") + ",orgname = " + context.getVariable("organization.name") + "}", "ip": context.getVariable("client.ip"), "messageid": context.getVariable("messageid"), "system.time": new Date().getTime().toString() }, "started_at": start_time, "duration": duration }; // Set the response content to the final JSON context.setVariable("custom.responseInfo", JSON.stringify(output));
  • Click Update to save the script

  • Now we need to add these scripts to the API flow to capture the information

  • Choose Flows → ProxyEndpoint PreFlow and under Extension Policies click add a Javascript policy:

    image-20250604-005901.png
  • Name the policy request_policy, make sure the Stream is set to Incoming Request then click Add:

    image-20250604-010020.png
  • In the request policy load the capture_request code:

    <!-- this policy allows us to execute java script code during execution of an API Proxy --> <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" xmlns='http://www.sap.com/apimgmt'> <!-- contains the name of the main code file --> <ResourceURL>jsc://capture_request.js</ResourceURL> </Javascript>
  • Choose Flows → ProxyEndpoint PostFlow and under Extension Policies click add a Javascript policy:

    image-20250604-010710.png
  • Name the policy response_policy, make sure the Stream is set to Outgoing Response then click Add:

  • In the response policy load the capture_response code:

    <!-- this policy allows us to execute java script code during execution of an API Proxy --> <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" xmlns='http://www.sap.com/apimgmt'> <!-- contains the name of the main code file --> <ResourceURL>jsc://capture_response.js</ResourceURL> </Javascript>
  • Choose Flows → ProxyEndpoint PostFlow and under Extension Policies click Message Logging:

    image-20250604-045133.png

     

  • Name the policy send_to_powerconnect, make sure the Stream is set to Outgoing Response then click Add:

    image-20250604-045207.png

     

  • Configure Message Logging to send syslog to your PowerConnect Cloud syslog receiver:

    <MessageLogging async="true" continueOnError="true" enabled="true" xmlns='http://www.sap.com/apimgmt'> <Syslog> <Message>{custom.responseInfo}</Message> <Host>insert host or ip</Host> <Port>insert port</Port> <Protocol>TCP</Protocol> <SSLInfo> <Enabled>false</Enabled> <ClientAuthEnabled>false</ClientAuthEnabled> <KeyStore/> <KeyAlias/> <TrustStore/> <Ciphers/> <Protocols/> </SSLInfo> </Syslog> </MessageLogging>
  • Enter the correct details for Host and Port

  • Click Update

  • Click Save

  • The API should now be sending JSON formatted data wrapped in syslog to your PowerConnect Cloud endpoint

  • Repeat the above steps for each API you wish to monitor