Customize HTTP access log in WSO2 API Manager 3.2.0 for custom request headers - wso2

We followed below documentation to print custom request headers in HTTP access log but facing some challenges
URL: https://apim.docs.wso2.com/en/3.2.0/administer/logging-and-monitoring/logging/monitoring-http-access-logs/
**Option 1**: We added below entries in /repository/conf/deployment.toml file
[http_access_log]
useLogger = true
pattern = "%{X-Forwarded-For}i %h %l %u %t %r %s %b %{Referer}i %{User-Agent}i %{X-Custom-Header}i %T"
The changes are reflecting in HOME\repository\conf\tomcat\catlina-server.xml but the custom headers are not getting printed.
**Option 2**: Created a separate log file as mentioned in "Configuring access logs for PassThrough or NIO transports in API Gateway" section. With this we are able to print the custom headers but the response code is not getting printed. It is appearing as "-".
Log format: access_log_pattern=%{X-Forwarded-For}i %h %l %u %t %r %s \"%{Referer}i\" \"%{User-Agent}i\" %{X-Custom-Header}i %B
Example log entry: - 10.73.122.48 - - [06/Dec/2022:14:49:36.628 +0530] "GET /mcm-stubs/testservice HTTP/1.1" **-** "-" "Synapse-PT-HttpComponents-NIO" "-" -
Please help

There are two sets of Access logs in API Manager. One for the Servlet components(Store/Publisher etc. what you access through ports 9443 and 9763) and the second for the Passthrough Transport(Accessed through 8280 and 8243). Sevlet Access Logs are handled by a Tomcat value and these configs can be changed by altering the deployment.toml which would reflect in the catlina-server.xml. These logs will be written to a separate file.
The Passthrough transport is where you will be receiving the actual API traffic and inorder to change the format. First, add the logger configs to <APIM_HOME>/repository/conf/log4j2.properties.
# Add the new logger to this line
loggers = PassThroughAccess, AUDIT_LOG, SERVICE_LOGGER, trace-messages,..........
# Define the new logger
logger.PassThroughAccess.name = org.apache.synapse.transport.http.access
logger.PassThroughAccess.level = INFO
Then create a new file named access-log.properties in <APIM_HOME>/repository/conf directory with the following content.
# Default access log pattern examples
#access_log_pattern=%{X-Forwarded-For}i %h %l %u %t \”%r\” %s %b \”%{Referer}i\” \”%{User-Agent}i\”
#access_log_pattern=time=%t remoteHostname=%h localPort=%p localIP=%A requestMethod=%m requestURL=%U remoteIP=%a requestProtocol=%H HTTPStatusCode=%s queryString=%q
# combinded log pattern
access_log_pattern=%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Custom-Header}i\"
# file prefix
access_log_prefix=http_gw
# file suffix
access_log_suffix=.log
# file date format
access_log_file_date_format=yyyy-MM-dd
Now restart the server and when you access an API the Access logs will be logged to a new file with the name you give in the above config. With the above configs logs will be written to <APIM_HOME>/repository/logs/http_gw.log
If this is a response header. You need to use the following pattern to get the header.
# To get a custom response Header
%{X-Custom-Header}o
# TO Get response code
%s
# A complete pattern
access_log_pattern=%h %l %u %t \"%r\" %s %b \"%{User-Agent}i\" customHeader=%{X-Custom-Header}o responseCode=%s
Update
You can't log the request headers in the response path. They will be logged in two separate lines, hence is difficult to correlate. One option is to pass the Custom Header to the backend and ask the backend to return the header with the response. Then you would see the same header in both request and response logs.
As Lakshitha mentioned another option is to manually log the header and the response. In order to do this, first, you need to extract the custom request header in the request path and then log it in the response path. There are two ways to do this, one is by creating a custom handler.
Another option is to use custom mediation policies. You can use the following two sequences for this. (Create following two files and upload them as custom policies)
Request: extractHeader.xml
<sequence xmlns="http://ws.apache.org/ns/synapse" name="extractHeader">
<property name="CUSTOM_HEADER" expression="$trp:X-Custom-Header" scope="default" />
</sequence>
Response: log_response_code.xml
<sequence xmlns="http://ws.apache.org/ns/synapse" name="log_in_response_code">
<log level="custom">
<property name="Header" expression="$ctx:CUSTOM_HEADER"/>
<property name="StatusCode" expression="$axis2:HTTP_SC"/>
</log>
</sequence>
Once applied it will look like this.

Option 2 is the correct approach to logging the API traffic. If you followed the steps in [1], for each request, there will be four lines of logs printed in the http_gw_<date>.log file. Those would be generated based on,
Request received by the gateway
Request passed to the backend
Response received from the backend
Response out from the gateway
You won't be able to log the response code in 1st and 2nd log lines as at that moment, the server is still yet to receive a response.
If your requirement is to log the custom header received from the gateway, you can easily achieve this with a mediator as below.
<log level="custom">
<property name="Header" expression="get-property('transport','X-Custom-Header')"/>
</log>
[1]- https://apim.docs.wso2.com/en/3.2.0/administer/logging-and-monitoring/logging/monitoring-http-access-logs/#configuring-access-logs-for-passthrough-or-nio-transports-in-api-gateway

Related

SMS is not received to mobile in SMPP Connector - WSO2 EI 6.5.0

I am using WSO2 SMPP Connector to send SMS to mobile number in WSO2 EI 6.5.0
Pre-requisites:
Setup done by using the same steps mentioned here
I just placed jsmpp-2.1.0-RELEASE.jar into <PRODUCT_HOME>/lib
logica-smpp-sim simulator set up done and it is running with the port 10003 in windows 10
API:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/send" name="SmppTestApi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<property expression="json-eval($.distinationAddress)" name="distinationAddress" scope="default" type="STRING"/>
<property expression="json-eval($.message)" name="message" scope="default" type="STRING"/>
<property expression="json-eval($.sourceAddress)" name="sourceAddress" scope="default" type="STRING"/>
<SMPP.init>
<host>localhost</host>
<port>10003</port>
<systemId>justin</systemId>
<password>justin</password>
<systemType>UNKNOWN</systemType>
<addressTon>UNKNOWN</addressTon>
<addressNpi>UNKNOWN</addressNpi>
</SMPP.init>
<SMPP.sendSMS>
<sourceAddress>{$ctx:sourceAddress}</sourceAddress>
<distinationAddress>{$ctx:distinationAddress}</distinationAddress>
<message>{$ctx:message}</message>
</SMPP.sendSMS>
<log level="full">
<property name="Message delivered sucessfully" value="Message delivered sucessfully"/>
</log>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
When I hit API , it is giving proper response as mentioned here
Postman:
Logica-sim log:
03:16:07 [justin] client request: (submit: (pdu: 108 4 0 3) (addr: 0 0 16111) (addr: 0 0 919047878787) (sm: msg: Hi! This is the first test SMS message.) (opt: ) )
03:16:07 [justin] putting message into message store
03:16:07 [justin] server response: (submit_resp: (pdu: 0 80000004 0 3) Smsc2002 )
WSO2 EI Log:
[2022-10-18 15:16:07,349] [] INFO - LogMediator To: /send, MessageID: urn:uuid:052d3fb7-1762-4323-bea1-5302ddc93d36 correlation_id : e5990fb5-fd97-45d2-b971-878d2471d9e5, Direction: request, Message delivered sucessfully = Message delivered sucessfully, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:messageId xmlns:ns="http://org.wso2.esbconnectors.smppConnector">Smsc2002</ns:messageId></soapenv:Body></soapenv:Envelope>
Note: I passed valid Indian Mobile number in the input request field (ie "distinationAddress")
I think SMS is stored in SMSC, But SMPP inbound endpoint will consume SMS from SMSC and send that to WSO2 EI Sequence.
I just want to understand in which stage SMS will send to corresponding mobile number which we passed in API Request.
Even though Received proper response SMS is not received to mentioned mobile.
Do I need to make any other configuration in API SMPP init level to send SMS? Kindly clarify on this.
The document you pointed out has this.
For testing purposes, it is not practical always to connect with a
real SMSC. SMSC Simulator is an application that can act like an SMSC.
Using a simulator we can test our scenario without having access to a
real SMSC. For the real production servers we have to use a real SMSC.
In this example scenario we will be using logica-smpp-sim simulator.
According to the above logica-smpp-sim is just a simulator, which is used to mimic an actual SMSC for testing. So I don't think it would send SMSs. You may have to connect to a real/production grade SMSC/SMPP Provider or an SMS Gateway if you want to send SMS. You can read more about the SMPP protocol and available Gateways from here.

sending XML file to http server

I am totally new to python and I am supposed to send a xml file to an url using request.put
the original xml file is :
<firewall>
<config name ="defaults">
.
.
.
</config>
</firewall>
but the file that server receives is :
--4812cb1ff13c4671b3b5789f09d4bb1d
Content-Disposition: form-data; name="firewall.xml"; filename="firewall.xml"
<firewall>
<config name ="defaults">
</config>
</firewall>
--4812cb1ff13c4671b3b5789f09d4bb1d--
I did whatever I could to remove the extra information before and after firewall tag but I could not.
here is the code that I have written:
import requests
url ='http://192.168.17.179/data/vhg/1112'
file_content = {'firewall.xml': open('firewall.xml','rb')}
header = {'Content-Type': 'raw'}
r= requests.put(url, files=file_content, headers=header)
print(r.status_code)

WSO2 API Manager: Always got HTTP OK response regardless of HTTP status code

I tried to set HTTP status code in response message in a custom mediator as followed
<property name="HTTP_SC" value="400" scope="axis2"/>
But in the response I got this status line
HTTP/1.1 400 OK
Is there anything else I need to do to get the correct HTTP status message which align with the HTTP status code.
I am using WSO2 API Manager 2.0.0
Thank you very much.
After dumping all properties in axis2 context, I found that I have to remove a property called 'HTTP_SC_DESC' to have HTTP status description correctly set
<property name="HTTP_SC_DESC" scope="axis2" action="remove"/>
After that I got correct HTTP status description
HTTP/1.1 400 Bad Request

WSO2 Identity Server 5.0.0 Logging X-Forwarded-For Header

I'm just wondering if it's possible to log the X-Forwarded-For Header in the log files?
It's a different WSO2 product but i have tried the following but it didn't appear to work: https://docs.wso2.com/display/ESB480/Access+Logs
Has anyone managed to do this?
Cheers
James
I changed the pattern attribute and made the application restart , so the client IP came to be logged in.
File: /idp/wso2is-4.5.0/repository/conf/tomcat/catalina-server.xml
...
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.wso2.carbon.tomcat.ext.realms.CarbonTomcatRealm"/>
<Host name="localhost" unpackWARs="true" deployOnStartup="false" autoDeploy="false" appBase="${carbon.home}/repository/deployment/server/webapps/">
<Valve className="org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve"/>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="${carbon.home}/repository/logs"
prefix="http_access_" suffix=".log"
pattern='%{X-Forwarded-For}i - %h %l %u %t "%r" %s %b %D ms' />
<Valve className="org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve" threshold="600"/>
<Valve className="org.wso2.carbon.tomcat.ext.valves.CompositeValve"/>
</Host>
</Engine>
...
Complementing: the client's IP is logged only in the "http_access_${date}.log" file.

WSO2 ESB: how to carry a SOAP answer into a file (or DB) using a scheduled task

I deploy a proxy service in WSO2 ESB that asks a web service for a dataset by a SOAP request and the web service correctly returns the requested dataset. In order to have evidence of the right answer of the web service, how can I do to store this dataset into a generic file during a regular scheduling in a task?
In your proxy def, you can find :
a inSequence executed when a request is sent to this proxy,
a outSequence that receive a response if you send a request from your inSequence (with send mediator)
a faultSequence executed if an error occurs.
So, if you "asks a web service for a dataset" from your inSequence using send mediator, your outSequence receive the response (your "dataset") and you just have to send it to a file :
<!-- name of the file -->
<property name="transport.vfs.ReplyFileName" value="dataset.xml" scope="transport"/>
<!-- OUT_ONLY because we want to use send mediator but don't want a callback waiting for a response -->
<property name="OUT_ONLY" value="true" />
<!-- Send current message (the response from your webService) to the filesystem : test directory must exist on c:\ -->
<send>
<endpoint>
<address uri="vfs:file:///C:/test"/>
</endpoint>
</send>
--> don't forget to activate VFS sender in repository/conf/axis2/axis2.xml : uncomment <transportSender name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportSender"/>