XML Logging
XML logging is one of the WinSCP log formats. An XML log includes structured records describing operations done by WinSCP over session. The log format is protocol independent.
In many cases you do not have to deal with the XML log file directly. WinSCP .NET assembly can do it for you.
Advertisement
- Purpose
- Using
- Representing Operations in Log
- Representing Results/Errors
- Grouping Operations for Commands
- Elements
- Schema
- Example
- Interpreting/Parsing
Advertisement
Purpose
Primary purpose of the XML logging is to provide machine-readable description of automatically performed operations, such as when using scripting.
The XML logging is useful e.g. to:
- Find a list of files that were actually uploaded/downloaded, when transferring a whole directory or when transferring files matching a mask;
- Get a directory listing;
- Record operations done during synchronization.
Note that while the XML logging can be used also for GUI sessions, it does not record background transfers.
Using
The XML logging, being used along with scripting, is most typically enabled from command-line, using /xmllog
parameter. It can be enabled in preferences too.
An overall format of the XML log file follows:
<?xml version="1.0" encoding="UTF-8"?> <session xmlns="http://winscp.net/schema/session/1.0" name="martin@example.com" start="2009-03-02T19:34:57.734Z"> <!-- operations --> </session>
The top level session
tag represents one logical session, which may consist of several physical sessions, particularly when connection is lost. Attribute name
refers to name of the logical session. Attribute start
indicates time when the session was initiated.1
The session
element includes child elements, where each element represents single log entry, i.e. single physical operation with remote file over the logical session.
Representing Operations in Log
Every entry in the XML log represents single physical operation over the session. Typically this would be an operation with remote file.
Single logical operation (in scripting or GUI) may actually involve multiple physical operations, each represented with separate log element. For example upload of file (e.g. using put
scripting command) may be represented by up to three elements, upload
for actual upload, touch
for preserving timestamp and chmod
for preserving permissions.
Note that some logical operations does not have corresponding log element (e.g. creation of symbolic link). Such operations are omitted from the XML log.
Representing Results/Errors
Results/Errors of Operations
Result of a specific operation is represented by child result
element of respective operation element. The result
element has boolean success
attribute.
Advertisement
<result success="true" />
If success
is false
, result
element will typically include one or more message
elements with error message(s). The error message is free text, that may be language-, protocol- or even server-specific. So you should not try to process it automatically.
The following example is from English version, connected with SFTP protocol to OpenSSH server:
<result success="false"> <message>Cannot open remote file '/home/user/examplefile.txt'.</message> <message>No such file or directory. Error code: 2 Error message from server: No such file Request code: 3</message> </result>
With some protocols, each of the physical operations are performed individually. With some protocols, set of operations may be performed in atomic form. This may prevent mapping error to specific operation. In this case the error may be associated with more operations, resulting in its duplication in the XML log.
Some errors may not be associated with any operation in the XML log. This particularly happens when:
- An error is actually not associated with particular physical operation. Example is invalid script command syntax.
- The particular operation that failed does not have corresponding log element.
Results/Errors of Script
When the script fails (WinSCP exit code is 1), the top level session
element or group
element (when grouping is enabled) will include one or more failure
elements, each containing one or more message
elements with error message(s).
If the particular error was associated with a physical operation, the error message will be included both in result
child element of the respective operation element and in failure
child element of top level session
element or group
element.
<upload> <filename value="d:\examplefile.txt" /> <result success="false"> <message>Cannot create remote file '/home/user/examplefile.txt'.</message> <message>Permission denied. Error code: 3 Error message from server: Permission denied Request code: 3</message> </result> </upload> <failure> <message>Cannot create remote file '/home/user/examplefile.txt'.</message> <message>Permission denied. Error code: 3 Error message from server: Permission denied Request code: 3</message> </failure>
Advertisement
Grouping Operations for Commands
When using the XML logging together with scripting, operations and failures belonging to the same command can be grouped using parent group
element:
<group name="put -preservetime d:\*.txt" start="2021-12-03T14:25:10.204Z"> <upload> <filename value="d:\readme.txt" /> <destination value="/home/user/readme.txt" /> <size value="15345" /> <result success="true" /> </upload> <upload> <filename value="d:\examplefile.txt" /> <result success="false"> <message>Cannot create remote file '/home/user/examplefile.txt'.</message> <message>Permission denied. Error code: 3 Error message from server: Permission denied Request code: 3</message> </result> </upload> <failure> <message>Cannot create remote file '/home/user/examplefile.txt'.</message> <message>Permission denied. Error code: 3 Error message from server: Permission denied Request code: 3</message> </failure> </group>
Grouping can be enabled on command-line.
Grouping is particularly useful, when you are continuously reading the XML log file. By receiving </group>
you know that the command execution has finished.
Elements
All operation elements below have result
child element in addition to listed child elements.
The result
child element is always present. Many other child elements may be absent in case of error.
call
Execution of arbitrary remote shell command (with SFTP and SCP protocols) or execution of a protocol command (with FTP protocol).
Elements:
Element | Description |
---|---|
command |
Command (in value attribute) |
destination |
Absolute path to current remote working directory (in value attribute) |
output |
Command standard output (in value attribute) |
erroroutput |
Command error output (in value attribute) |
Advertisement
Example:
<call> <command value="ps" /> <destination value="/home/user" /> <output value=" PID TTY TIME CMD 16969 ? 00:00:00 sshd 16970 ? 00:00:00 sftp-server 32647 ? 00:00:00 bash 1466 ? 00:00:00 ps" /> <result success="true" /> </call>
Associated script commands: call
checksum
Calculating a checksum of a remote file.
Elements:
Element | Description |
---|---|
filename |
Absolute path to a remote file (in value attribute) |
algorithm |
Name of a checksum algorithm used (in value attribute) |
checksum |
Hex dump of a calculated checksum (in value attribute) |
Example:
<checksum> <filename value="/home/martin/public_html/index.html" /> <algorithm value="sha-1" /> <checksum value="bb4dfa9b51d3f6c99b5ec6c12ebf9cade79f43c4" /> <result success="true" /> </checksum>
Associated script commands: checksum
chmod
Changing of permissions of one (or more) remote file.
Elements:
Element | Description |
---|---|
filename |
Absolute path to remote file (in value attribute) |
permissions |
Permissions in Unix format rwxrwxrwx (in value attribute) |
Advertisement
With SCP protocol optional boolean attribute recursive
indicates, if permissions were changed recursively with single operation.
Example:
<chmod recursive="true"> <filename value="/home/martin/public_html/about.html" /> <permissions value="rwxr-xr-x" /> <result success="true" /> </chmod>
Associated script commands: chmod
, keepuptodate -permissions
, put -permissions
, synchronize remote|both -permissions
cp
Duplication of one remote file or directory.
Elements:
Element | Description |
---|---|
filename |
Absolute path to source local file (in value attribute) |
destination |
Absolute path to destination remote file (in value attribute) |
Example:
<cp> <filename value="/home/martin/public_html/about.html" /> <destination value="/home/martin/backup/about.html.20171220" /> <result success="true" /> </cp>
Associated script commands: cp
download
Downloading of single file.
Elements:
Element | Description |
---|---|
filename |
Absolute path to source remote file (in value attribute) |
destination |
Absolute path to destination local file (in value attribute)2 |
size |
Number of bytes transferred. |
Advertisement
Example:
<download> <filename value="/home/martin/public_html/about.html" /> <destination value="d:\www\about.htm" /> <size value="55387" /> <result success="true" /> </download>
Associated script commands: get
, synchronize local|both
ls
Listing of remote directory (only when explicitly requested using ls
scripting command).
Elements:
Element | Description |
---|---|
destination |
Absolute path to remote directory (in value attribute) |
files |
Container of file elements |
Elements of file
element:
Element | Description |
---|---|
filename |
Name of file without path (in value attribute) |
type |
Type of file as in Unix ls command output, e.g. d for directory (in value attribute) |
size |
Size of file in bytes (in value attribute) |
modification |
Modification timestamp (in value attribute)1 |
permissions |
File permissions in Unix format rwxrwxrwx (in value attribute) |
owner |
File owner (in value attribute) |
group |
File group (in value attribute) |
Example:
<ls> <destination value="/home/martin/public_html" /> <files> <file> <filename value="." /> <type value="d" /> <modification value="2008-12-22T12:16:23.000Z" /> <permissions value="rwxr-xr-x" /> </file> <file> <filename value=".." /> <type value="d" /> <modification value="2008-03-25T08:15:53.000Z" /> <permissions value="rwxr-xr-x" /> </file> <file> <filename value=".htaccess" /> <type value="-" /> <size value="107" /> <modification value="2008-12-02T06:59:58.000Z" /> <permissions value="rw-r--r--" /> </file> <file> <filename value="about.html" /> <type value="-" /> <size value="24064" /> <modification value="2007-10-04T21:43:02.000Z" /> <permissions value="rw-r--r--" /> </file> </files> <result success="true" /> </ls>
Advertisement
Associated script commands: ls
mkdir
Elements:
Element | Description |
---|---|
filename |
Absolute path to remote directory (in value attribute) |
Example:
<mkdir> <filename value="/home/martin/public_html/images" /> <result success="true" /> </mkdir>
Associated script commands: keepuptodate
, mkdir
, put
, synchronize remote|both
mv
Moving of one remote file or directory to different remote directory or renaming of one remote file or directory.
Elements:
Element | Description |
---|---|
filename |
Absolute path to source local file (in value attribute) |
destination |
Absolute path to destination remote file (in value attribute)2 |
Example:
<mv> <filename value="/home/martin/public_html/about.html" /> <destination value="/tmp/about.bak" /> <result success="true" /> </mv>
Associated script commands: mv
rm
Deleting of one (or more) remote file or directory.
Advertisement
Elements:
Element | Description |
---|---|
filename |
Absolute path to remote file of directory (in value attribute) |
With SCP protocol optional boolean attribute recursive
indicates, if remote directory was recursively deleted with all contained files with single operation.
Example:
<rm recursive="true"> <filename value="/home/martin/public_html/images" /> <result success="true" /> </rm>
Associated script commands: get -delete
, keepuptodate -delete
, rm
, rmdir
, synchronize local|both -delete
stat
Listing of remote file attributes.
Elements:
Element | Description |
---|---|
filename |
Absolute path to remote file (in value attribute) |
file |
Container of file attributes. See specification in description of ls element. Note that file element within stat misses filename subelement, comparing to file element within ls /files . |
Example:
<stat> <filename value="/home/martin/public_html/about.html" /> <file> <type value="-" /> <size value="24064" /> <modification value="2007-10-04T21:43:02.000Z" /> <permissions value="rw-r--r--" /> </file> <result success="true" /> </stat>
Associated script commands: stat
upload
Uploading of single file.
Advertisement
Elements:
Element | Description |
---|---|
filename |
Absolute path to source local file (in value attribute) |
destination |
Absolute path to destination remote file (in value attribute)2 |
size |
Number of bytes transferred. |
Example:
<upload> <filename value="d:\www\about.htm" /> <destination value="/home/martin/public_html/about.html" /> <size value="55387" /> <result success="true" /> </upload>
Associated script commands: keepuptodate
, put
, synchronize remote|both
touch
Changing of remote file timestamp.
Elements:
Element | Description |
---|---|
filename |
Absolute path to remote file (in value attribute) |
modification |
Modification timestamp (in value attribute)1 |
Example:
<touch> <filename value="/home/martin/public_html/about.html" /> <modification value="2008-12-28T11:22:19.000Z" /> <result success="true" /> </touch>
Associated script commands: keepuptodate
, put -preservetime
, synchronize remote|both
Schema
An XML schema for the XML log is available at: http://winscp.net/schema/session/1.0
Advertisement
Example
Note that the group
elements will be included, if enabled only.
<?xml version="1.0" encoding="UTF-8"?> <session xmlns="http://winscp.net/schema/session/1.0" name="martin@example.com" start="2012-01-04T14:25:53.173Z"> <group name="put -preservetime -permissions=644 d:\www\about.htm" start="2012-01-04T14:28:45.393Z"> <upload> <filename value="d:\www\about.htm" /> <destination value="/home/martin/public_html/about.html" /> <result success="true" /> </upload> <touch> <filename value="/home/martin/public_html/about.html" /> <modification value="2008-12-28T11:22:19.000Z" /> <result success="true" /> </touch> <chmod> <filename value="/home/martin/public_html/about.html" /> <permissions value="rw-r--r--" /> <result success="true" /> </chmod> </group> <group name="rm about.bak" start="2012-01-04T14:28:47.892Z"> <rm> <filename value="/home/martin/public_html/about.bak" /> <result success="false"> <message>No such file or directory. Error code: 2 Error message from server: No such file Request code: 13</message> </result> </rm> <failure> <message>No such file or directory. Error code: 2 Error message from server: No such file Request code: 13</message> </failure> </group> </session>
Interpreting/Parsing
General
To parse the XML log, use any XML parser available.
Advertisement
If possible, using WinSCP .NET assembly is the preferred approach, which hides away the XML log file from your application.
If you want to parse the XML log yourself anyway, see following guides to learn how to do that in different development environments:
- Advanced FTP/SFTP scripting (Windows script host; Java or VB script);
- SFTP file transfers in .NET (.NET; C# or VB.NET);
- Interpreting XML log for advanced scripting (.NET, C#).
Transforming XML Log to Text Output Using XSLT Transformation
You can use XSLT transformation to convert the XML log to plain text output (or any other format).
For example to generate a plain text list of successfully downloaded files from the following XML log (log.xml
):
<?xml version="1.0" encoding="UTF-8"?> <session xmlns="http://winscp.net/schema/session/1.0" name="user@host" start="2021-12-03T06:45:57.008Z"> <download> <filename value="/path/file1.txt" /> <destination value="C:\path\file1.txt" /> <size value="2022" /> <result success="true" /> </download> <download> <filename value="/path/file2.txt" /> <destination value="C:\path\file2.txt" /> <size value="5782" /> <result success="true" /> </download> </session>
use the following XSLT (download.xslt
):
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:winscp="http://winscp.net/schema/session/1.0"> <xsl:output method="text" encoding="UTF-8"/> <xsl:strip-space elements="*"/> <xsl:template match='winscp:download[winscp:result[@success="true"]]/winscp:filename'> <xsl:value-of select="@value"/> <xsl:text>
</xsl:text> </xsl:template> </xsl:stylesheet>
You can execute it using any XSLT processor:
- .NET
XslCompiledTransform
class, e.g. from PowerShell:
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform $xslt.Load("download.xslt") $xslt.Transform("log.xml", "download.txt")
- Libxml2
xsltproc.exe
:
xsltproc.exe download.xslt log.xml
Advertisement
The output will be:
/path/file1.txt /path/file2.txt
For a more complex example, see Custom directory listing format (CSV).