Skip to content

Conversation

@bhufmann
Copy link
Contributor

What it does

  • This PR adds a trace-server developer guide as markdown file under folder doc/traceserver
  • It splits the org.eclipse.tracecompass.example plugin into org.eclipse.tracecompass.example.core and org.eclipse.tracecompass.example.ui. With this the o.e.tc.example.core plugin can be added to the trace-server application.
  • It updates existing examples to make it work again.
  • It adds new examples to support the description in the developer guide

How to test

  • Open developer guide in Markdown viewer
  • Add the o.e.tc.example.core plug-in to trace-server and try the examples
  • Add o.e.tc.example.core and o.e.tc.example.ui to Eclipse Trace Compass RCP to try the examples for the Eclipse-based Trace Compass.

Follow-ups

Review checklist

  • As an author, I have thoroughly tested my changes and carefully followed the instructions in this template

@bhufmann bhufmann force-pushed the dev-guide branch 4 times, most recently from fc8f117 to 7849e84 Compare May 20, 2025 18:26
bhufmann added 2 commits May 21, 2025 15:49
- This allows to add the example.core plugin to the trace server
- In Eclipse Trace Compass no change, but both core and UI have to be
included
- Fix bugs in example data providers
- Updated developer guide to reflect this update.

[Changed] Split example plugin into core and  UI plug-in

Signed-off-by: Bernd Hufmann <[email protected]>
[Added] Example data tree data provider to the examples.core plugin

Signed-off-by: Bernd Hufmann <[email protected]>
@bhufmann bhufmann force-pushed the dev-guide branch 2 times, most recently from 66d940c to 222504c Compare May 21, 2025 19:58

private static final IDataProviderDescriptor DESCRIPTOR = new DataProviderDescriptor.Builder()
.setId(ID)
.setName("Example configuarable time graph") //$NON-NLS-1$
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configurable

.setName("Example configuarable time graph") //$NON-NLS-1$
.setDescription("This is an example of a configurable time graph data provider using a state system analysis as a source of data") //$NON-NLS-1$
.setProviderType(ProviderType.TIME_GRAPH)
.build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing setting the canCreate capability to true?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


The purpose of Trace Compass trace server is to facilitate the integration of trace analysis and visualization using client applications that implement the `Trace Server Protocol`, for example, the `vscode-trace-extension` or `tsp-python-client`.

This guide goes over the internal components of the Trace Compass framework and how to add . It should help developers trying to add new capabilities (support for new trace type, new analysis or views, etc.) to the framework. End-users, using the RCP for example, should not have to worry about the concepts explained here.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how to add ???

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

## Key Concepts

### Analysis
An `analysis` module in Trace Compass is an entity that consumes trace events of a trace and/or experiment, performs some computation, for example CPU or memory usage, use state machines to track analayse states of a system, follows key characterisics stored trace events and much more. `analysis` modules may persit (e.g. using a state system) the results on disk so that those computations don't need to be re-done every time the data is requested.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

analayse > analysis?
characteristics
persist

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


### Configuration

A `configuration` is the data structure to configure and customize the trace server back-end globaly (e.g. load XML analysis) or to configure data providers with parameters.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

globally

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if (configId == null) {
return baseId;
}
return baseId + DataProviderConstants.ID_SEPARATOR + configId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONFIG_SEPARATOR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep ID_SEPARATOR as stated earlier.

* @return data provider ID using a config ID.
*/
public static String generateID(String configId) {
return ExampleConfigurableDataTreeDataProviderFactory.ID + DataProviderConstants.ID_SEPARATOR + configId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONFIG_SEPARATOR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As state earlier I would like to keep ID_SEPARATOR to avoid confusion, because sometimes it needs to be the ID_SEPARATOR for secondary IDs, in in other cases it can be either nor neither.

fTrace = trace;
fConfiguration = configuration;
if (configuration != null) {
fId = BASE_ID + DataProviderConstants.ID_SEPARATOR + configuration.getId();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONFIG_SEPARATOR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this example it has to be the ID_SEPARATOR because it needs to be the secondary ID of the data provider ID that the DataProviderManager is extracting by API contract.

if (configId == null) {
return baseId;
}
return baseId + DataProviderConstants.ID_SEPARATOR + configId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONFIG_SEPARATOR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as per comments above I'll keep it.

fModule = module;
ITmfConfiguration config = module.getConfiguration();
if (config != null) {
fId = ID + DataProviderConstants.ID_SEPARATOR + config.getId();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONFIG_SEPARATOR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above

Copy link
Contributor Author

@bhufmann bhufmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comments

fTrace = trace;
fConfiguration = configuration;
if (configuration != null) {
fId = BASE_ID + DataProviderConstants.ID_SEPARATOR + configuration.getId();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It actually has to be the ID_SEPARATOR because the secondary ID is actually the configuration ID and the DataProviderManager will pass it to the createDataProvider(trace, secondaryId).

    public @Nullable ITmfDataProvider createDataProvider(@NonNull ITmfTrace trace, String secondaryId) {
        ITmfConfiguration config = fConfigurator.getConfiguration(trace, secondaryId);
        if (trace instanceof TmfExperiment) {
            List<ExampleConfigurableDataTreeDataProvider> list = TmfTraceManager.getTraceSet(trace)
                .stream()
                .map(tr -> new ExampleConfigurableDataTreeDataProvider(tr, config))
               .toList();
            return new TmfTreeCompositeDataProvider<>(list, ExampleDataTreeDataProviderConfigurator.generateID(secondaryId));
        }
        return new ExampleConfigurableDataTreeDataProvider(trace, config);
    }

fModule = module;
ITmfConfiguration config = module.getConfiguration();
if (config != null) {
fId = ID + DataProviderConstants.ID_SEPARATOR + config.getId();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It prefer to keep it with ID_SEPARATOR. The DataProviderManager is able to handle that even if a ID has 2 ID_SEPARATORS in the name, as long as the first one is secondaryID for the data provider create methods.

    ....
    String[] ids = id.split(DataProviderConstants.ID_SEPARATOR, 2);
    ...

.setName("Example configuarable time graph") //$NON-NLS-1$
.setDescription("This is an example of a configurable time graph data provider using a state system analysis as a source of data") //$NON-NLS-1$
.setProviderType(ProviderType.TIME_GRAPH)
.build();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

* @return data provider ID using a config ID.
*/
public static String generateID(String configId) {
return ExampleConfigurableDataTreeDataProviderFactory.ID + DataProviderConstants.ID_SEPARATOR + configId;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It needs to be the ID_SEPARATOR here.

if (configId == null) {
return baseId;
}
return baseId + DataProviderConstants.ID_SEPARATOR + configId;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep ID_SEPARATOR as stated earlier.

fTrace = trace;
fConfiguration = configuration;
if (configuration != null) {
fId = BASE_ID + DataProviderConstants.ID_SEPARATOR + configuration.getId();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this example it has to be the ID_SEPARATOR because it needs to be the secondary ID of the data provider ID that the DataProviderManager is extracting by API contract.

- `IDataProviderDescriptor createDataProviderDescriptors(ITmfTrace trace, ITmfConfiguration configuration)`
When called, the configuration needs to be applied, i.e. create analysis module with the configuration, add the analysis module to the trace and/or experiment persist the configuration on disk and cache the configuration inside the class.
- `void removeDataProviderDescriptor(ITmfTrace trace, IDataProviderDescriptor descriptor)`
This method will remove the configuration, all stored information and persisted data corresponding the derived data provider whose desciptor is passed to the method. For that remove the analysis module(s) from traces or experiment and delete persisted data (e.g. state system)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if (configId == null) {
return baseId;
}
return baseId + DataProviderConstants.ID_SEPARATOR + configId;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as per comments above I'll keep it.

.setId(ID)
.setName("Example configuarable time graph") //$NON-NLS-1$
.setDescription("This is an example of a configurable time graph data provider using a state system analysis as a source of data") //$NON-NLS-1$
.setProviderType(ProviderType.TIME_GRAPH)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

fModule = module;
ITmfConfiguration config = module.getConfiguration();
if (config != null) {
fId = ID + DataProviderConstants.ID_SEPARATOR + config.getId();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above

=======
The configuration source type descibes the input parameters to provide when to pass when creating a new data provider or global configuration.
>>>>>>> 222504c42f (doc: Add global configuration to trace-server developer guide)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge conflict

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


### Implementing a configurable data provider without analysis module

To demonstrate how to implement a configurable data provider that doesn't use an analyis module, we will modify the data provider of chapter [Implementing data provider without analysis module](#implementing-a-data-provider-without-analysis-module). Please note that the class name and package names are different to be able to have independent examples in the example plug-in.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a small-h hufmann at line 2758 that looks like a revert from a merge resolution.

bhufmann added 2 commits May 29, 2025 16:18
- Add developer guide in markdown in doc/trace-server folder
- Update and create example classes in the o.e.tc.example.core plug-in

Signed-off-by: Bernd Hufmann <[email protected]>
@bhufmann bhufmann merged commit 7074455 into eclipse-tracecompass:master May 30, 2025
4 checks passed
@bhufmann bhufmann deleted the dev-guide branch May 30, 2025 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet