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 & Channels
Channels
Xtend
EB RACE built-in script language
Execution Context
Overview
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