OnixS C++ CME Market Data Handler  2.56.0.0
Replaying Log Files

Using Logs to Replay Market Data

In normal flow, Handler logs all important aspects of its execution onto file system. Log files include also original market data processed by the Handler. This information is usually saved for analysis of non-standard situations which may occur during use of the Handler. However, it also can be used to reproduce normal Handler's behavior for a certain period of time.

Once Handler was executed with logging enabled, it's possible to use log files for further replay. First of all, logs must be backed up (copied to another location) or Handler's configuration must be updated to use another directory for new logs. This is because current implementation of the Handler doesn't support replay from the same folder in which new logs will be stored.

Note
Handler will not replay log files produced by itself with logging mode set to OnixS::CME::MarketData::LogModes::Disabled and OnixS::CME::MarketData::LogModes::Important. This is because no required data is saved in those modes. To produce log files suitable for further replay Handler's logging must be configured with OnixS::CME::MarketData::LogModes::Regular or OnixS::CME::MarketData::LogModes::Debug logging mode. None of advanced logging options (OnixS::CME::MarketData::LogModes::AdvancedLogOptions constants) has influence on replay.

Afterwards, instance of OnixS::CME::MarketData::ReplayOptions class must be constructed and initialized with the logs to replay. The easiest way is to use one of OnixS::CME::MarketData::ReplayOptions class constructors which accepts channel identifier and path to the folder with logs to replay as a parameters:

ReplayOptions replayOptions("11", "replay");

This constructor will automatically gather all logs from the specified directory for the specified channel.

Alternatively, it's possible manually define list of log files to be replayed. Manually manipulating list of log files allows replaying log files whose names differ from names used by the Handler.

ReplayOptions replayOptions;
options.logs.push_back("1.log");
options.logs.push_back("2.log");
options.logs.push_back("3.log");
Note
Files to be replayed must be in exact order as they were recorded by the Handler and belong to single run cycle.

When configuring the options is accomplished, replay can be started. For this purpose, OnixS::CME::MarketData::Handler::start overload is to be called to start replaying. Replaying is performed by the Handler asynchronously in same way as regular execution flows. From client code point of view, there's no difference whether Handler processes market from the network or from log files.

Note
Handler fires appropriate events as soon as market data is received from the network and processed. However, since CME environment spreads market data with different frequency which depends on live market activity, there're delays of different duration between fired events. When log file is replayed, Handler does not do any pauses and fires corresponding events as soon as data is retrieved from the log file.

To stop the Handler to replay log files, OnixS::CME::MarketData::Handler::stop member can be used.

When replay is accomplished Handler will call OnixS::CME::MarketData::ReplayListener::onReplayFinished member of the OnixS::CME::MarketData::ReplayListener class. To get notified about this and other replay-related events it's necessary to implement OnixS::CME::MarketData::ReplayListener class interface and supply an instance of the derived class to the Handler using OnixS::CME::MarketData::ReplayOptions::listener member.

Note
When market data is being replayed, OnixS::CME::MarketData::Message::getReceivingTime member returns time of corresponding log file entry. That's the value returned represents original time when market data message was obtained from the network.
Currently, log replay must be run with the same set of Handler's settings which were originally used.

Example

Following example demonstrates how to replay log files backed up into 'replay' folder:

using namespace OnixS::CME::MarketData;
class MyReplayListener : public ReplayListener
{
public:
MyReplayListener()
{
}
~MyReplayListener()
{
}
void onReplayError(const ChannelId& channelId, const string& errorDescription)
{
cout << "Log replay error on channel '" << channelId << "': " << errorDescription << endl;
}
void onReplayFinished(const ChannelId& channelId)
{
cout << "Log replay finished on channel '" << channelId << "'." << endl;
}
};
const string channel = "11";
HandlerSettings settings;
settings.channelId = channel;
settings.logDirectory = "logs";
Handler handler(settings);
MyReplayListener replayListener;
ReplayOptions replayOptions(channel, "replay");
replayOptions.listener = &replayListener;
handler.start(replayOptions);
...
handler.stop();