Trace Parser: add Readme and user guide 73/160873/12
authorAlexander Aksenov <a.aksenov@samsung.com>
Mon, 20 Nov 2017 09:41:26 +0000 (12:41 +0300)
committerAlexander Aksenov <a.aksenov@samsung.com>
Tue, 28 Nov 2017 15:34:55 +0000 (18:34 +0300)
Change-Id: I7508dff6c5cf32e851a05dc3a3daeb5eee88eebf
Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
src/cli/trace_parser/README [new file with mode: 0644]
src/cli/trace_parser/docs/MAINTAIN.md [new file with mode: 0644]
src/cli/trace_parser/docs/Makefile [new file with mode: 0644]
src/cli/trace_parser/docs/README.md [new file with mode: 0644]
src/cli/trace_parser/docs/readme.css [new file with mode: 0644]
src/cli/trace_parser/docs/workflow.png [new file with mode: 0644]
src/cli/trace_parser/include/data_writer.h
src/cli/trace_parser/include/parser.h

diff --git a/src/cli/trace_parser/README b/src/cli/trace_parser/README
new file mode 100644 (file)
index 0000000..bc69828
--- /dev/null
@@ -0,0 +1,22 @@
+SWAP Trace Parser
+Copyright (c) 2017 Samsung Electronics Co., Ltd.
+
+- Full user guide
+
+Full user and development guides are located at docs/README.md, and
+docs/MAINTAIN.md, they are Markdown-formatted. To compile, enter the following:
+$ cd docs && make
+README.html, README.pdf and MAINTAIN.pdf will appear at docs/output.
+
+- Build
+
+Run in Trace Parser folder:
+$ ./build.sh
+Generated binaries will be located in bin/
+
+- Quick start
+
+Run in a directory that contains built binaries:
+
+$ ./swap_parser -t output_type [text|py|json|csv] -s section_data_from_target \
+                -i input_file -o output_file
diff --git a/src/cli/trace_parser/docs/MAINTAIN.md b/src/cli/trace_parser/docs/MAINTAIN.md
new file mode 100644 (file)
index 0000000..bbbe7d0
--- /dev/null
@@ -0,0 +1,74 @@
+# SWAP Trace Parser development and support
+
+**Trace Parser** consists of two binaries: *swap_parser* executable and *libspp.so* library. ***libspp.so*** implements
+protocol parsing: it splits binary data bundle to meaningful values and calls output methods for them. These output
+methods are specified at ***swap_parser***. It also contains command-line arguments handling, *session_data.json* and
+*api_map_list* files parsing. It is also contains read loop which performs reading data from file and passing it to
+protocol parser.
+
+There are two main instances which interact with each other: DataWriter and Protocol.
+
+Protocol directly parses binary data and passes it to DataWriter for output.
+
+DataWriter output data by the specified way, depends on output type.
+
+**Trace Parser** workflow can be illustrated by the following image:
+
+@image latex workflow.png
+
+Solid arrow stands for interactions between executable's main and library's Parser interface class invoked by the
+Executable.
+
+Dashed arrow stands for interactions invoked by the Library.
+
+1. Trace Parser executable gets arguments from command-line, prepares in and out streams, chooses and creates proper
+DataWriter object, initializes Parser object with these data;
+2. Before starting parsing loop, header size for the specified protocol version is received by the executable;
+3. Parsing loop is started;
+4. Message header of size specified by the current protocol is received from input stream;
+5. This data bundle is passed to Parser for header parsing;
+6. While parsing, Protocol object calls DataWriter primitives for data outputting;
+7. DataWriter primitives perform data outputting according to an internal implementation;
+8. Header parsing function returns Header object with message header information;
+9. Message's payload data length is taken from Header object and the data is received from input stream;
+10. Payload data bundle is passed to parser;
+11. While parsing payload, Protocol object calls DataWriter primitives for data outputting;
+12. These primitives perform data outputting as it is implemented inside them.
+
+Steps 4-12 are executed in a loop, until input stream is not empty.
+
+
+## Interfaces
+***libspp.so*** provides two interfaces: one for its initialization (*include/parser.h*) and one as an abstract base
+class for DataWriter implementations (*include/data_writer.h*).
+The first one contains [Header](@ref HeaderDef) and [Parser](@ref ParserDef) interfaces.
+The second one contatins [DataWriter](@ref DataWriterDef) interface.
+
+*output_\*(...)* functions perform output in specified style and are called by parser when the value is parsed.
+*start_\*()* and *finish_\*()* functions are called when parser reaches some special places like message start,
+object start, array start and finishes for them. These functions can be used as control ones for DataWriter and
+for data output depending on the specified output type.
+
+## Custom data output development
+While ***libspp.so*** contains protocol descriptions which are actually very rare to change, these is also a
+capability to add implementations of user-defined output formats. Data output is represented as a class inherited
+from abstract DataWriter class which implements output methods. These methods are called by protocol parser strictly
+one after another which makes it easy to determine current place of parsing: is it message header, payload, some array
+or object inside etc.
+
+Additional data output can be implemented both as a part of ***swap_parser*** or as just a class to be used
+outside of ***swap_parser*** binary, for example in any outstanding project.
+
+For the first case, data output implementation should include not only inherited DataWriter methods implementation
+of the given type, but also supporting output type in ***swap_parser*** (parsing its command-line argument, creating
+proper writer etc.). Command-line arguments are parser inside *session_data.cpp* module, type is got there and
+passed to *writers.cpp* module. Here all writers are included and *get_data_writer()* function makes a decision which
+of them should be used depending on a command-line type argument. So, here the new data output type name should be
+placed and command-line type argument checking should be added for it as for all other data output classes. If you
+want to update usage message, return to *session_data.cpp* and add it here to *boost::program_options::options
+description desc.add_options()*.
+
+For the second case, you should develop DataWriter class basing on the *output_\*()* and *start_\*()/finish_\*()*
+functions one after another calling, so you can always be sure, that for the valid binary trace, data that comes first
+is parsed first: message is always started with *start_msg()* and finished with *finish_msg()*, all arrays started
+with *start_array()* and finished with *finish_array()* and so on.
diff --git a/src/cli/trace_parser/docs/Makefile b/src/cli/trace_parser/docs/Makefile
new file mode 100644 (file)
index 0000000..a6ea79f
--- /dev/null
@@ -0,0 +1,29 @@
+SUBDIR := latex
+OUTDIR := output
+
+all: pdf_maintain pdf_readme html_readme install
+
+# Make html using pandoc
+html_readme:
+       pandoc -f markdown+pipe_tables+escaped_line_breaks+pandoc_title_block -t html5 --css readme.css -s README.md -o README.html
+
+pdf_readme:
+       pandoc -f markdown+pipe_tables+escaped_line_breaks+pandoc_title_block  -s README.md -o README.pdf
+
+pdf_maintain: $(SUBDIR)
+       cp latex/refman.pdf ./MAINTAIN.pdf
+
+$(SUBDIR):
+       doxygen Doxyfile
+       $(MAKE) -C $@
+
+install: html_readme pdf_readme pdf_maintain
+       mkdir -p $(OUTDIR)
+       install -m 644 MAINTAIN.pdf README.html README.pdf readme.css $(OUTDIR)
+
+clean:
+       rm -r latex
+       rm README.pdf README.html MAINTAIN.pdf
+       rm -r $(OUTDIR)
+
+.PHONY: all pdf_maintain pdf_readme html_readme clean
diff --git a/src/cli/trace_parser/docs/README.md b/src/cli/trace_parser/docs/README.md
new file mode 100644 (file)
index 0000000..945bffb
--- /dev/null
@@ -0,0 +1,146 @@
+%SWAP Trace Parser user guide
+
+**Trace Parser** is a part of **SWAP tool**. It is used for parsing binary trace, gathered by System Wide Analyzer Performance (**SWAP**) and outputting it in a specified format. **Trace Parser** supports several output types:\
+- text output;\
+- trace as a python source file output;\
+- JSON formatted output;\
+- CSV formatted output.
+
+It also provides an interface for custom output module implementation.
+For more details about **SWAP tool** you can see its *README* file.
+
+## Get sources
+**Trace Parser** is provided as a source code. To use **Trace Parser** first you need to build it. It requires *cmake (2.8 version or newer)* and *C++ boost libraries* for its built.
+To build **Trace Parser** please do the following steps:
+
+- clone **swap-manager** sources and checkout to *tizen* branch:
+``` bash
+$ git clone git://git.tizen.org/platform/core/system/swap-manager
+$ cd swap-manager && git checkout tizen
+```
+## Build
+- go to **Trace Parser** source directory and run *build.sh* script:
+``` bash
+$ cd swap-manager/src/cli/trace_parser
+$ ./build.sh
+```
+- after script is finished, **Trace Parser** is built. You can find it in *bin/* directory:
+``` bash
+$ ls bin/
+libspp.so  swap_parser
+```
+## Run
+Besides **SWAP** trace, **Trace Parser** also requires some additional data about gathered trace: trace protocol version, target device/emulator info about CPU cores count and count of energy devices located on target (its top energy consumers, like *LCD*, *CPU*, *WiFI* and so on). Optionally, API map list can be added from the target: it provides additional data about gathered API functions.
+User can specify trace data manually or, which is most preferable, take it from output directory of **SWAP tool** with the trace. File named *session_data.json* contains all the necessary data for tracing.
+API map list file can also be found at the output of **SWAP tool**, it's named *api_map_list*.
+
+### Protocol versions
+**Trace Parser** supports the following protocol versions:
+
+| Version |
+|---------|
+| 3.0     |
+| 4.0     |
+| 4.1     |
+| 4.2     |
+Protocol version should be chosen the same as one on the target where the trace was gathered. For detailed information and protocol description, please refer to Protocol Description located at *swap-manager/docs/protocol.rst* or at **swap-manager** *README* file.
+
+If user hasn't specified any protocol version, ***4.2*** protocol version will be used as default.
+
+### Output types
+**Trace Parser** supports the following output types:
+
+| Type   | Short | Description                            |
+| ------ | ----- | -------------------------------------- |
+| text   | t     | Output in human-readable text format   |
+| python | p     | Output is formatted like python module |
+| json   | j     | Output in JSON format                  |
+| csv    | c     | Output in comma-separated value format |
+
+You can specify the type by its name (*Type column*) or short name (*Short column*).
+
+#### Text output format
+``` text
+msg_id = 0x1                            //message ID number in hex format
+seq_num = 0                             //message sequence number
+sec = 1510680912                        //second when event has occurred
+usec = 436919901                        //microsecond when event has occurred
+payload_len = 8617                      //length of message specific data
+...                                     // Rest is message specific information
+=============================           // Such line separates messages
+```
+
+#### Python output format
+``` python
+trace_info = {           # Contains data about parsed trace
+'protocol_version': 42   # Trace's protocol version
+}
+trace obj = [            # Array that contains all trace messages. Each message is a dictionary
+{'msg_id': 0x1,          # Message ID number in hex
+'seq_num': 0,            # Message sequence number
+'sec': 1510680912,       # Second when event has occurred
+'usec': 436919901,       # Microsecond when event has occurred
+'payload_len': 8617,     # Length of message specific data
+...,                     # Message specific data
+},
+...                      # Other messages
+]
+```
+#### JSON output format
+``` json
+{
+"trace_info" : {         # Contains data about parsed trace
+"protocol_version" : 42  # Trace's protocol version
+},
+"trace_obj" : [          # Contains all trace messages
+{"msg_id" : 1,           # Message ID number
+"seq_num': 0,            # Message sequence number
+"sec": 1510680912,       # Second when event has occurred
+"usec": 436919901,       # Microsecond when event has occurred
+"payload_len": 8617,     # Length of message specific data
+...                      # Message specific data
+},
+...                      # Other messages
+]
+```
+#### CSV output format
+
+| Message ID | Sequence number | Second      | Microsecond | Length | Message specific data |
+| ---------- | --------------- | ----------- | ----------- | ------ | --------------------- |
+| 0x1,       | 0,              | 1510680912, | 436919901,  | 8617,  | ...                   |
+
+### Execution
+**Trace Parser** supports the following command-line arguments:
+
+| Argument     | Options | Description |
+| ------------ | ------- | ----------- |
+| help (h)     |         | Print usage |
+| input (i)    | input file path       | Path to trace file. If not specified, trace is taken from *stdio*. **Optional** |
+| session (s)  | session data file    | Path to *session_data.json* file. If not specified, target data is taken from command line arguments or default. **Optional** |
+| api_map (a)  | API map list file     | Path to *api_map_list* file. **Optional** |
+| output (o)   | output file path      | Path to output file. If not specified, data outputted to *stdout*. **Optional** |
+| cpu_num (c)  | CPUs number           | Number of CPUs at the target device. If not specified, is taken from *session_data.json* or default. **Optional** |
+| devs_num (d) | energy devices number | Number of energy devices on target. If not specified, is taken from *session_data.json* or default. **Optional** |
+| version (v)  | protocol version      | Protocol version. If not specified, is taken from *session_data.json* or default. **Optional** |
+| type (t)     | output type           | Output format |
+
+You can run **Trace Parser** by running the following command in a directory, which contains *swap_parser* executable and *libspp.so* library. For example, with *session_data.json* and *api_map_list* specified:
+``` bash
+./swap_parser -i trace.bin -o trace.txt -s session_data.json -a api_map_list -t text
+```
+This command will read *trace.bin*, parse it into text format and output to *trace.txt*.
+The same command, if target info data is specified manually:
+``` bash
+./swap_parser -i trace.bin -o trace.txt -c 4 -d 5 -v 4.2 -a api_map_list -t text
+```
+If user wants to use default data, it will be like the following:
+``` bash
+./swap_parser -i trace.bin -o trace.txt -t text
+```
+Or the minimum command, that expects trace at *stdin* and outputs it to *stdout*:
+``` bash
+./swap_parser -t text
+```
+\
+\
+For **Development and support** guide see *MAINTAIN* files.
diff --git a/src/cli/trace_parser/docs/readme.css b/src/cli/trace_parser/docs/readme.css
new file mode 100644 (file)
index 0000000..41db826
--- /dev/null
@@ -0,0 +1,24 @@
+body {
+   font-family: Arial, Helvetica, sans-serif;
+}
+
+table {
+   border-collapse: collapse;
+}
+
+table td, table th {
+    border: 1px solid #ddd;
+    padding: 8px;
+}
+
+table tr:nth-child(even) {
+    background-color: #cceaca;
+}
+
+table th {
+    padding-top: 12px;
+    padding-bottom: 12px;
+    text-align: left;
+    background-color: #4caf50;
+    color: white;
+}
diff --git a/src/cli/trace_parser/docs/workflow.png b/src/cli/trace_parser/docs/workflow.png
new file mode 100644 (file)
index 0000000..263664b
Binary files /dev/null and b/src/cli/trace_parser/docs/workflow.png differ
index e366180c5b96927d97ac29898c610b5bf0be5d7f..154ff9d031ea7dbe715df2fadbb4ca025338c70a 100644 (file)
 #ifndef __DATA_WRITER_H__
 #define __DATA_WRITER_H__
 
+//! \file data_writer.h
+//! Abstract class DataWriter - interface for output implementation
+
 #include <string>
 #include <vector>
 #include <sstream>
 
-
+//! # DataWriter {#DataWriterDef}
+//! Interface for writers implementation
 class DataWriter
 {
 public:
+    //! Inited with output stream
     DataWriter(std::iostream &ios) : ios_(ios) {}
 
+    //! Called at trace start
     virtual void start_file(const uint32_t version) = 0;
+    //! Called at trace finish
     virtual void finish_file() = 0;
 
+    //! Called at start message
     virtual void start_msg() = 0;
+    //! Called at finish message
     virtual void finish_msg() = 0;
 
+    //! uint8_t output
     virtual void output_val(const std::string &name, const uint8_t val) = 0;
+    //! uint32_t output
     virtual void output_val(const std::string &name, const uint32_t val) = 0;
+    //! uint64_t output
     virtual void output_val(const std::string &name, const uint64_t val) = 0;
+    //! float output
     virtual void output_val(const std::string &name, const float val) = 0;
+    //! double output
     virtual void output_val(const std::string &name, const double val) = 0;
+    //! string output
     virtual void output_val(const std::string &name,
                             const std::string &val) = 0;
+    //! char output
     virtual void output_val(const std::string &name, const char val) = 0;
+    //! int output
     virtual void output_val(const std::string &name, const int val) = 0;
 
+    //! uint32_t output in hex
     virtual void output_hex(const std::string &name, const uint32_t val) = 0;
+    //! uint64_t output in hex
     virtual void output_hex(const std::string &name, const uint64_t val) = 0;
 
+    //! bool args and ret val output
     virtual void output_args(const std::string &name, const bool val) = 0;
+    //! uint8_t args and ret val output
     virtual void output_args(const std::string &name, const uint8_t val) = 0;
+    //! uint32_t args and ret val output
     virtual void output_args(const std::string &name, const uint32_t val) = 0;
+    //! uint64_t args and ret val output
     virtual void output_args(const std::string &name, const uint64_t val) = 0;
+    //! float args and ret val output
     virtual void output_args(const std::string &name, const float val) = 0;
+    //! double args and ret val output
     virtual void output_args(const std::string &name, const double val) = 0;
+    //! string args and ret val output
     virtual void output_args(const std::string &name,
                              const std::string &val) = 0;
+    //! For void functions
     virtual void output_args(const std::string &name) = 0;
+    //! float array args
     virtual void output_args(const std::string &name,
                              const std::vector<float> &val, uint64_t p) = 0;
+    //! uint32_t array args
     virtual void output_args(const std::string &name,
                              const std::vector<uint32_t> &val, uint64_t p) = 0;
+    //! uint64_t hex args out
     virtual void output_args_hex(const std::string &name,
                                  const uint64_t val) = 0;
 
+    //! Output time
     virtual void output_time(const std::string &name, uint64_t val) = 0;
+    //! Output binary buffer
     virtual void output_buf(const std::vector<char> &buf) = 0;
+    //! Called at array output start
     virtual void start_array(const std::string &name) = 0;
+    //! Called at array output finish
     virtual void finish_array() = 0;
+    //! Called at object output start
     virtual void start_object(const std::string &name) = 0;
+    //! Called at object output finish
     virtual void finish_object() = 0;
 
 protected:
-    std::iostream &ios_;
+    std::iostream &ios_;        //!< Contains stream for output
 
 };
 
index ecbf5f24105c5cdb13a200be3352f551ee008592..1beea08ebb09014cabca0a6e14ac63ce0bdf225d 100644 (file)
@@ -29,6 +29,9 @@
 #ifndef __PARSER_H__
 #define __PARSER_H__
 
+//! \file parser.h
+//! Contains Parser interface
+
 #include <memory>
 #include <string>
 #include <map>
 
 class Protocol;
 
+//! # Header {#HeaderDef}
+//! Contains parsed message header, returned from parse_header().
 class Header
 {
 public:
+    //! Initialized with message header data
     Header(uint32_t id, uint32_t seq, uint32_t sec, uint32_t usec, uint32_t len) :
         id_(id), seq_(seq), sec_(sec), usec_(usec),len_(len) {}
+    //! Returns message ID
     uint32_t get_id() const { return id_; };
+    //! Returns message sequence number
     uint32_t get_seq() const { return seq_; };
+    //! Returns second of the event
     uint32_t get_sec() const { return sec_; };
+    //! Returns microsecond of the event
     uint32_t get_usec() const { return usec_; };
+    //! Returns message specific data length
     size_t get_msg_len() const { return len_; };
 
 private:
-    uint32_t id_;
-    uint32_t seq_;
-    uint32_t sec_;
-    uint32_t usec_;
-    uint32_t len_;
+    uint32_t id_;       //!< Message id
+    uint32_t seq_;      //!< Message sequence number
+    uint32_t sec_;      //!< Second of the event
+    uint32_t usec_;     //!< Microsecond of the event
+    uint32_t len_;      //!< Message-specific data length
 };
 
-// Structure used to initialize Parser.
+//! # ParserOptions (#ParserOptionsDef)
+//! Structure used to initialize Parser.
 struct ParserOptions
 {
-    const std::string version;
-    const int cpu_num;
-    const int devs_num;
-    std::shared_ptr<DataWriter> writer;
-    std::map<int, std::string> &api_map;
+    const std::string version;             //!< Trace's protocol version
+    const int cpu_num;                     //!< Number of traget CPUs
+    const int devs_num;                    //!< Number of target energy devices
+    std::shared_ptr<DataWriter> writer;    //!< Writer pointer
+    std::map<int, std::string> &api_map;   //!< Reference to API map list
 
+    //! Initialized with structure members
     ParserOptions(const std::string &version, const int cpu_num, const int devs_num,
                   std::shared_ptr<DataWriter> writer, std::map<int, std::string> api_map) :
         version(version),
@@ -75,15 +88,25 @@ struct ParserOptions
     {}
 };
 
-// Main Parser class
+//! # Parser {#ParserDef}
+//! Main Parser class, encapsulates Protocol classes instances
 class Parser
 {
 public:
+    //! Initialization with init structure
     Parser(const ParserOptions &init_data);
+    //! Function for trace parsing beginning
     void start_file() const;
+    //! Function for trace parsing finishing
     void finish_file() const;
+    //! Returns header size for specified protocol
     size_t get_header_size() const;
+    //! Parses header and returns it in Header object.
+    //! buf - reference to binary data bundle
     const Header parse_header(const std::vector<char> &buf) const;
+    //! Parses message payload.
+    //! buf - reference to binary data bundle;
+    //! header - to parsed message header.
     void parse_payload(const std::vector<char> &buf, const Header &header) const;
 
 private: