EB RACE
Script Tutorial
-
Getting started
- Hello World (1 Minute Tutorial)
- Detmerine CPU Peaks (5 Minute Tutorial)
-
EB RACE Script API
- Events & Channels
- Timemarkers
- Charts & Tables
- Decoder
- Tagging Events
- HTML 5 & JavaScript Callbacks
-
Behind the scenes
- Xtend - The script language
- Execution context
- Lifecycle of a script
- Download, unzip and launch EB RACE
- Apply for a license key
- Re-start EB RACE and enter your license key
- Click on "Start with Demo Files"
- You are now ready to implement your first script
Hello World
Prerequisites
Hello World
Create a New Script
Go to the Resource Explorer and select New -> New Script
Hello World
Give your script a name
Give the script a meaningful name. You don't need to add a file extension, since it will be auto-completed with .xtend.
Xtend is the language that is internally used as scripting language. Learn more about Xtend.
Hello World
Select a execution context
Scripts can be executed in various contexts. Select Global context and proceed with Finish.
Learn more about execution contexts later.
Hello World
The generated script skeleton
class HelloWorld
{
extension RaceScriptContext _raceScriptContext
extension RaceScriptBase _raceScriptBase
new (RaceScriptContext raceScriptContext) {
_raceScriptContext = raceScriptContext
_raceScriptBase = new RaceScriptBase(_raceScriptContext)
}
/**
* Add a meaningful content to the description tag to describe the feature, which is executed by this script
* The content of the description tag will be used in all UI widgets where the script can be invoked
* If the content is empty, then the classname.methodname will be used instead
*/
@Execute(context=ExecutionContext.GLOBAL, description="")
def executeScript() {
}
}
The new script HelloWorld.xtend will be created an opened in the editor. The basic code of your script will be created automatically for you. It contains a constructor, that will give you access to the EB RACE API. Therefore the constructor MUST NOT be touched. Additionally the skeleton of your script method will be generated. Methods with the annotation @Execute will automatically recognized from EB RACE. Learn more here.
Hello World
Add a console prompt to your script
class HelloWorld
{
extension RaceScriptContext _raceScriptContext
extension RaceScriptBase _raceScriptBase
new (RaceScriptContext raceScriptContext) {
_raceScriptContext = raceScriptContext
_raceScriptBase = new RaceScriptBase(_raceScriptContext)
}
/**
* Add a meaningful content to the description tag to describe the feature, which is executed by this script
* The content of the description tag will be used in all UI widgets where the script can be invoked
* If the content is empty, then the classname.methodname will be used instead
*/
@Execute(context=ExecutionContext.GLOBAL, description="")
def executeScript() {
/* YOUR CONSOLE PROMPT */
consolePrintln("Hello EB RACE Script")
}
}
Hello World
Execute your script
The new script HelloWorld.xtend will be created an opened in the editor.Scripts which are annotated with ExecutionContext.GLOBAL can be executed within the Resource Explorer.
Go to the folder Scripts, navigate to your script and execute it.
Hello World
See the result
As usual for a "Hello World" example we have picked the most simple use-case. Printing a string into the console.
The console will be opened automatically in EB RACE.
Continue with this tutorial for more elaborated scripts.
Determine CPU Peaks
Use Case Description
We want to determine the highest value of a channel (i.e. the global peak) and visualize it as a time-marker. We want to apply this function for arbitrary channels and display the result in a line chart together with the markers.
Determine CPU Peaks
Setting the execution context
@Execute(context=ExecutionContext.PRESELECTION, description="Create a time-marker for the highest value")
def tutorial01(RuntimeEventChannel<?> channel) {
}
We want to call the script, in the context of the channel explorer.
So we need to set the ExecutionContext to PRESELECTION and add a RuntimeEventChannel as parameter.
The script is now registered and can be called.
And we can now add our code into the generated skeleton.
Determine CPU Peaks
Retrieve the events from a channel
@Execute(context=ExecutionContext.PRESELECTION, description="Create a time-marker for the highest value")
def tutorial01(RuntimeEventChannel<?> channel) {
// get all events from a channel
channel.events
}
First we need to get access to all events within the given channel.
This is a simple EB RACE API call:
Detmerine CPU Peaks
Determine the peak value
@Execute(context=ExecutionContext.PRESELECTION, description="Create a time-marker for the highest value")
def tutorial01(RuntimeEventChannel<?> channel) {
// sort the events from a channel by its values and pick the highest (i.e. the ast element of the list)
channel.events.sortBy[value as Double].last
}
To determine the event with the highest value, we need to sort the list of events and take the last entry from the list.
This is pure Xtend functionality
Determine CPU Peaks
Create a timemarker
@Execute(context=ExecutionContext.PRESELECTION, description="Create a time-marker for the highest value")
def tutorial01(RuntimeEventChannel<?> channel) {
channel.events.sortBy[value as Double].last.createTimemarker("CPU Peak "+channel.name)
}
Since we have picked the event with the peak value, we can now create a marker at the given time-stamp and give the marker a meaningful name.
Detmermine CPU Peaks
Create a chart and jump to the marker
@Execute(context=ExecutionContext.PRESELECTION, description="Create a time-marker for the highest value")
def tutorial01(RuntimeEventChannel<?> channel) {
channel.events.sortBy[value as Double].last.createTimemarker("CPU Peak "+channel.name).jumpTo
createOrGetChart("CPU Load Overview", CHART_TYPE.LINE_CHART).add(channel)
}
Then visualize the cpu values in a chart and jump to the marker, that has just been created.
Determine CPUPeaks
See the result
See what happens, when the script is applied on several channels
Events & Channels
Events
- Events carry the basic run-time data of your system, such as cpu load, memory consumption, ipc messages, trace and logging data, etc.
- Events can either be acquired from a target agent plug-in and sent to EB RACE or created by an importer directly in EB RACE.
- An event always comes with a time-stamp along with any kind of value, whereas the value can be of primitive type or of any arbitrary complex type.
- Complex types can be transformed into structured trees by a corresponding decoder.
- Events can be accessed and created by use of the internal Script API
Events & Channels
Channels
- Channels are container for events of the same kind of data
- They do have a unique names, such as "cpu.p:targetagent:3460", whereas the "." in the name serves as a separator in the hierarchical channel view
- Channels with events of
- numeric types (e.g. integer, double, etc.) can be visualized in Line Charts and Tables
- boolean type can be visualized in Gantt Charts and Tables
- complex types can be visualized in the decoder view as part of an EB RACE Table
- Channels can be accessed and created by use of the internal Script API
Xtend
EB RACE built-in script language
- Xtend is using the Java type-system and hence allows a seamless integration into an Eclipse RCP application, what EB RACE is.
- Xtend code will be generated into Java source code on-the-fly in the background, so that no additional interpreter is needed at runtime.
- Xtend is a hybrid language that combines object-oriented and functional programming at the same time, which allows the implementation of very expressive and concise scripts.
- You have the full power of Java with some syntactical sugar on top.
- Eclipse editor functionality like content-assist, code completion, referencing is the same as for Java.
Execution Context
Overview
- In order to allow the best possible ease of use the scripts are designed to be executed directly within the EB RACE GUI.
- Depending on your use case scenario (e.g. postmortem vs. live analysis) you can tell EB RACE how to execute your scripts.
- This will be achieved by annotating your script methods with the tag @Execute and a corresponding context.
- There are three different context available:
- Global
- Preselection
- Callback
Execution Context
Example Use Case
In order to explain the different execution contexts, take following use case, where you want to create a time-marker, whenever your cpu load is higher than 50%:
Scenario 1: You want to do the analysis post-mortem and you know your corresponding channel is named "cpu.system"
Scenario 2: You want to do the analysis for any kind of channel
Scenario 3: You want to do the anaylsis in case of live connection
Execution Context
Scenario 1 (Global)
@Execute(context=ExecutionContext.GLOBAL, description="")
def createMarkerForHighCpuLoad() {
// you as a developer need to indicate the channel,
// in this case "cpu.system".channel
getChannel("cpu.system").events.filter[value as Double > 50].
forEach[createTimemarker("High CPU Load")]
}
Scenario 1: You want to do the analysis post-mortem and you know your corresponding channel is named "cpu.system"
Execution Context
Preselection
@Execute(context=ExecutionContext.PRESELECTION, description="")
def createMarkerForHighCpuLoad(RuntimeEventChannel<?> channel) {
// The channel was already selected by the user within the GUI
// and can be accessed as parameter
channel.allEventsFromChannel.filter[value as Double > 50].
forEach[createTimemarker("High CPU Load")]
}
Scenario 2: You want to do the analysis for any kind of channel
Execution Context
Callback
@Execute(context=ExecutionContext.CALLBACK, description="")
def createMarkerForHighCpuLoad(List<RuntimeEvent<?>> events) {
// You need to check if the list of events contain information
// from the channel you are interested in.
events.filter[channelName.equals("cpu.system")].
filter[value as Double > 50].
forEach[createTimemarker("High CPU Load")]
}
Scenario 3: You want to do the anaylsis in case of live connection
Execution Context
Summary
Context | Description |
---|---|
GLOBAL | The script developer can assume to have access to all events from all channels collected by EB RACE so far. This context is usually chosen in post-mortem analysis. The script is started by the user in the resource explorer and stops when the end of the executable method is reached. It can be stopped explicitly in case it is a long running script. |
PRESELECTION | The pre-selection mode differs from the global mode insofar as the context of the data where the script is to be executed is already select by the user. E.g. in context of a channel, a timemarker or a runtime event |
CALLBACK | The callback mode is usually chosen during live connection or for big data files. The script is notified continuously after a certain time-interval with new events. The script is started and also stopped by the user explicitly. In case the Callback mode is used in conjunction with EB RACE Auto the script is stopped when the end of file is reached. |
Lifecycle of a Script
Overview
Similar to a JUnit-Test an EB RACE Script follows the paradigm, that a script can undergo certain life cycle stages, where you can implement startup and cleanup code, if needed.
When creating a new script, the wizard asks you to generate corresponding skeletons for your method.
Lifecycle of a Script
Generated Code
@BeforeRaceScript
def setupScript() {
// Your setup code
}
@Execute(context=ExecutionContext.GLOBAL, description="My description")
def executeScript() {
// Your script code
}
@AfterRaceScript
def cleanup() {
// Your cleanup code
}
setup
cleanup
execution
optional
optional
Lifecycle of a Script
The rules and workflow
- You are free to rename method names, the annotations are decisive.
- Every script is invoked with the order: @BeforeRaceScript -> @Execute -> @AfterRaceScript.
- The startup and cleanup methods are optional, they are only invoked when they are available.
- The lifecycle order applies for all execution contexts (Global, Preselection and Callback) in the same way.
- Whenever a script is stopped explicitly by the user (e.g. when ending a callback script during live-connection) the @AfterRaceScript method is called (if available).
EB RACE Script Tutorial
By Torsten Mosis
EB RACE Script Tutorial
EB RACE - Script tutorial
- 202