diff options
author | Guilliano Molaire | 2014-04-23 16:51:11 +0000 |
---|---|---|
committer | Genevieve Bastien | 2014-04-30 14:27:14 +0000 |
commit | 33fd02d5b7047bedf174413126371b124af39fe7 (patch) | |
tree | c500112d08b6c310680383c6867dadcfcb35d057 | |
parent | cdba39011f87d0672850f1ddbe9cce4206bebc84 (diff) | |
download | org.eclipse.linuxtools-33fd02d5b7047bedf174413126371b124af39fe7.tar.gz org.eclipse.linuxtools-33fd02d5b7047bedf174413126371b124af39fe7.tar.xz org.eclipse.linuxtools-33fd02d5b7047bedf174413126371b124af39fe7.zip |
TMF: Possibility to generate a session configuration from a ISessionInfo
With this feature we are able to generate a XML session configuration which
can be used to recreate a trace session on the target side.
Change-Id: I9786f322842b5166376f67d522907fa6bdc84edb
Signed-off-by: Guilliano Molaire <guilliamo-jaime.molaire@polymtl.ca>
Reviewed-on: https://git.eclipse.org/r/23425
Tested-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Tested-by: Genevieve Bastien <gbastien+lttng@versatic.net>
11 files changed, 1201 insertions, 3 deletions
diff --git a/lttng/org.eclipse.linuxtools.lttng2.core.tests/META-INF/MANIFEST.MF b/lttng/org.eclipse.linuxtools.lttng2.core.tests/META-INF/MANIFEST.MF index ebfb28e627..5497d26999 100644 --- a/lttng/org.eclipse.linuxtools.lttng2.core.tests/META-INF/MANIFEST.MF +++ b/lttng/org.eclipse.linuxtools.lttng2.core.tests/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: org.junit;bundle-version="4.0.0", org.eclipse.core.runtime, - org.eclipse.linuxtools.lttng2.core;bundle-version="3.0.0" + org.eclipse.linuxtools.lttng2.core;bundle-version="3.0.0", + org.eclipse.linuxtools.tmf.core;bundle-version="3.0.0" Export-Package: org.eclipse.linuxtools.lttng2.core.tests;x-friends:="org.eclipse.linuxtools.lttng.alltests", org.eclipse.linuxtools.lttng2.core.tests.control.model.impl;x-internal:=true diff --git a/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/AllTests.java b/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/AllTests.java index 6248314ea8..41ff5dcaae 100644 --- a/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/AllTests.java +++ b/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/AllTests.java @@ -22,7 +22,8 @@ import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ ActivatorTest.class, - org.eclipse.linuxtools.lttng2.core.tests.control.model.impl.AllTests.class + org.eclipse.linuxtools.lttng2.core.tests.control.model.impl.AllTests.class, + org.eclipse.linuxtools.lttng2.core.tests.session.AllTests.class }) public class AllTests { diff --git a/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/session/AllTests.java b/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/session/AllTests.java new file mode 100644 index 0000000000..985e99cd69 --- /dev/null +++ b/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/session/AllTests.java @@ -0,0 +1,26 @@ +/********************************************************************** + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Guilliano Molaire - Initial API and implementation + *********************************************************************/ +package org.eclipse.linuxtools.lttng2.core.tests.session; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Run all the tests in the lttng2.core.session plugin. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + SessionConfigGeneratorTest.class +}) +public class AllTests { + +} diff --git a/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/session/SessionConfigGeneratorTest.java b/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/session/SessionConfigGeneratorTest.java new file mode 100644 index 0000000000..78fb9ea68f --- /dev/null +++ b/lttng/org.eclipse.linuxtools.lttng2.core.tests/src/org/eclipse/linuxtools/lttng2/core/tests/session/SessionConfigGeneratorTest.java @@ -0,0 +1,155 @@ +/********************************************************************** + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Guilliano Molaire - Initial API and implementation + *********************************************************************/ +package org.eclipse.linuxtools.lttng2.core.tests.session; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.linuxtools.internal.lttng2.core.Activator; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.IDomainInfo; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.ISessionInfo; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.TraceSessionState; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.impl.BufferType; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.impl.SessionInfo; +import org.eclipse.linuxtools.lttng2.core.session.SessionConfigGenerator; +import org.eclipse.linuxtools.lttng2.core.session.SessionConfigStrings; +import org.eclipse.linuxtools.lttng2.core.tests.control.model.impl.ModelImplFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * This class contains tests for the class {@link SessionConfigGenerator}. + */ +public class SessionConfigGeneratorTest { + + // ------------------------------------------------------------------------ + // Test data + // ------------------------------------------------------------------------ + + /** Session files for validation */ + private static final File VALID_SESSION_FILE = new File("../org.eclipse.linuxtools.lttng2.core.tests/test_session_config_files/test_valid.lttng"); + private static final File INVALID_SESSION_FILE = new File("../org.eclipse.linuxtools.lttng2.core.tests/test_session_config_files/test_invalid.lttng"); + + private static final String SESSION_FILENAME = "test_session." + SessionConfigStrings.SESSION_CONFIG_FILE_EXTENSION; + private static final IPath SESSION_FILE_PATH = Activator.getDefault().getStateLocation().addTrailingSeparator().append(SESSION_FILENAME); + private static final String TRACE_SESSION_PATH = "/home/user/folder"; + + private static final String SESSION_NAME_1 = "session1"; + private static final String SESSION_NAME_2 = "session2"; + private static final String SESSION_NAME_3 = "session3"; + + /** Session informations for generation tests */ + private ISessionInfo fValidSessionInfo = null; + private ISessionInfo fValidSessionSnapshotInfo = null; + private ISessionInfo fInvalidSessionInfo = null; + + // ------------------------------------------------------------------------ + // Housekeeping + // ------------------------------------------------------------------------ + /** + * Perform pre-test initialization. + */ + @Before + public void setUp() { + /* A valid domain with shared buffer type */ + ModelImplFactory factory = new ModelImplFactory(); + IDomainInfo domain = factory.getDomainInfo1(); + domain.setBufferType(BufferType.BUFFER_SHARED); + + /* The valid sessions */ + fValidSessionInfo = new SessionInfo(SESSION_NAME_1); + fValidSessionInfo.setSessionPath(TRACE_SESSION_PATH); + fValidSessionInfo.setSessionState(TraceSessionState.ACTIVE); + fValidSessionInfo.addDomain(domain); + + fValidSessionSnapshotInfo = new SessionInfo(SESSION_NAME_2); + fValidSessionSnapshotInfo.setSessionPath(TRACE_SESSION_PATH); + fValidSessionSnapshotInfo.setSessionState(TraceSessionState.ACTIVE); + fValidSessionSnapshotInfo.addDomain(domain); + fValidSessionSnapshotInfo.setSnapshotInfo(factory.getSnapshotInfo1()); + + /* The invalid session contains an event with an invalid type */ + fInvalidSessionInfo = factory.getSessionInfo2(); + fInvalidSessionInfo.setName(SESSION_NAME_3); + } + + /** + * Delete the session file created + */ + @After + public void tearUp() { + /* Tear up the file created if it exists */ + File sessionConfigurationFile = SESSION_FILE_PATH.toFile(); + if (sessionConfigurationFile.exists()) { + sessionConfigurationFile.delete(); + } + + } + + // ------------------------------------------------------------------------ + // Tests + // ------------------------------------------------------------------------ + + /** + * Test method for {@link SessionConfigGenerator#sessionValidate(File)} + */ + @Test + public void testSessionValidate() { + File testSessionFile = VALID_SESSION_FILE; + if ((testSessionFile == null) || !testSessionFile.exists()) { + fail("Session test file does not exist"); + } + IStatus status = SessionConfigGenerator.sessionValidate(testSessionFile); + if (!status.isOK()) { + fail(status.getMessage()); + } + + testSessionFile = INVALID_SESSION_FILE; + if ((testSessionFile == null) || !testSessionFile.exists()) { + fail("Session test file does not exist"); + } + assertFalse(SessionConfigGenerator.sessionValidate(testSessionFile).isOK()); + } + + /** + * Test method for + * {@link SessionConfigGenerator#generateSessionConfig(Set, IPath)} + */ + @Test + public void testGenerateSessionConfig() { + /* Should fail since it's empty */ + final Set<ISessionInfo> sessions = new HashSet<>(); + assertFalse(SessionConfigGenerator.generateSessionConfig(sessions, SESSION_FILE_PATH).isOK()); + + /* Add a valid session and validate */ + sessions.add(fValidSessionInfo); + assertTrue(SessionConfigGenerator.generateSessionConfig(sessions, SESSION_FILE_PATH).isOK()); + assertTrue(SessionConfigGenerator.sessionValidate(SESSION_FILE_PATH.toFile()).isOK()); + + /* Add a valid snapshot session and validate */ + sessions.add(fValidSessionSnapshotInfo); + assertTrue(SessionConfigGenerator.generateSessionConfig(sessions, SESSION_FILE_PATH).isOK()); + assertTrue(SessionConfigGenerator.sessionValidate(SESSION_FILE_PATH.toFile()).isOK()); + + /* Add an invalid session */ + sessions.add(fInvalidSessionInfo); + assertFalse(SessionConfigGenerator.generateSessionConfig(sessions, SESSION_FILE_PATH).isOK()); + } +} diff --git a/lttng/org.eclipse.linuxtools.lttng2.core.tests/test_session_config_files/test_invalid.lttng b/lttng/org.eclipse.linuxtools.lttng2.core.tests/test_session_config_files/test_invalid.lttng new file mode 100644 index 0000000000..d13f485874 --- /dev/null +++ b/lttng/org.eclipse.linuxtools.lttng2.core.tests/test_session_config_files/test_invalid.lttng @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+ <!--***************************************************************************
+ * Copyright(C) 2014 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Guilliano Molaire - Initial API and implementation
+ ***************************************************************************
+ This is an invalid session configuration file. The domain type
+ is missing.-->
+<sessions>
+ <session>
+ <name>auto-20140323-130527</name>
+ <started>false</started>
+ <domains>
+ <domain>
+ <buffer_type>GLOBAL</buffer_type>
+ <channels>
+ <channel>
+ <name>channel0</name>
+ <overwrite_mode>DISCARD</overwrite_mode>
+ <subbuffer_count>4</subbuffer_count>
+ <switch_timer_interval>0</switch_timer_interval>
+ <tracefile_size>0</tracefile_size>
+ <tracefile_count>0</tracefile_count>
+ <live_timer_interval>0</live_timer_interval>
+ <enabled>false</enabled>
+ <subbuffer_size>262144</subbuffer_size>
+ <read_timer_interval>200000</read_timer_interval>
+ <output_type>SPLICE</output_type>
+ <events>
+ <event>
+ <name>exit_syscall</name>
+ <enabled>true</enabled>
+ <type>TRACEPOINT</type>
+ </event>
+ </events>
+ </channel>
+ </channels>
+ </domain>
+ </domains>
+ <output>
+ <consumer_output>
+ <enabled>true</enabled>
+ <destination>
+ <path>/home/user/folder</path>
+ </destination>
+ </consumer_output>
+ </output>
+ </session>
+</sessions>
diff --git a/lttng/org.eclipse.linuxtools.lttng2.core.tests/test_session_config_files/test_valid.lttng b/lttng/org.eclipse.linuxtools.lttng2.core.tests/test_session_config_files/test_valid.lttng new file mode 100644 index 0000000000..4dea4df351 --- /dev/null +++ b/lttng/org.eclipse.linuxtools.lttng2.core.tests/test_session_config_files/test_valid.lttng @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+ <!--***************************************************************************
+ * Copyright(C) 2014 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Guilliano Molaire - Initial API and implementation
+ ***************************************************************************
+ This is a valid session configuration file. All mandatory
+ elements are provided.-->
+<sessions>
+ <session>
+ <name>auto-20140323-130527</name>
+ <started>false</started>
+ <domains>
+ <domain>
+ <type>KERNEL</type>
+ <buffer_type>GLOBAL</buffer_type>
+ <channels>
+ <channel>
+ <name>channel0</name>
+ <overwrite_mode>DISCARD</overwrite_mode>
+ <subbuffer_count>4</subbuffer_count>
+ <switch_timer_interval>0</switch_timer_interval>
+ <tracefile_size>0</tracefile_size>
+ <tracefile_count>0</tracefile_count>
+ <live_timer_interval>0</live_timer_interval>
+ <enabled>false</enabled>
+ <subbuffer_size>262144</subbuffer_size>
+ <read_timer_interval>200000</read_timer_interval>
+ <output_type>SPLICE</output_type>
+ <events>
+ <event>
+ <name>exit_syscall</name>
+ <enabled>true</enabled>
+ <type>TRACEPOINT</type>
+ </event>
+ </events>
+ </channel>
+ </channels>
+ </domain>
+ </domains>
+ <output>
+ <consumer_output>
+ <enabled>true</enabled>
+ <destination>
+ <path>/home/user/folder</path>
+ </destination>
+ </consumer_output>
+ </output>
+ </session>
+</sessions>
diff --git a/lttng/org.eclipse.linuxtools.lttng2.core/META-INF/MANIFEST.MF b/lttng/org.eclipse.linuxtools.lttng2.core/META-INF/MANIFEST.MF index 94c7cbe27f..744585be53 100644 --- a/lttng/org.eclipse.linuxtools.lttng2.core/META-INF/MANIFEST.MF +++ b/lttng/org.eclipse.linuxtools.lttng2.core/META-INF/MANIFEST.MF @@ -8,7 +8,8 @@ Bundle-SymbolicName: org.eclipse.linuxtools.lttng2.core;singleton:=true Bundle-Activator: org.eclipse.linuxtools.internal.lttng2.core.Activator Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Require-Bundle: org.eclipse.core.runtime +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.linuxtools.tmf.core;bundle-version="3.0.0" Export-Package: org.eclipse.linuxtools.internal.lttng2.core;x-friends:="org.eclipse.linuxtools.lttng2.core.tests", org.eclipse.linuxtools.internal.lttng2.core.control.model;x-friends:="org.eclipse.linuxtools.lttng2.ui,org.eclipse.linuxtools.lttng2.ui.tests,org.eclipse.linuxtools.lttng2.core.tests", org.eclipse.linuxtools.internal.lttng2.core.control.model.impl;x-friends:="org.eclipse.linuxtools.lttng2.ui,org.eclipse.linuxtools.lttng2.ui.tests,org.eclipse.linuxtools.lttng2.core.tests", diff --git a/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/Messages.java b/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/Messages.java new file mode 100644 index 0000000000..b58bd33986 --- /dev/null +++ b/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/Messages.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Guilliano Molaire - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng2.core.session; + +import org.eclipse.osgi.util.NLS; + +/** + * Externalized message strings from the lttng2.core.control.session + * + * @author Guilliano Molaire + * @since 3.0 + */ +@SuppressWarnings("javadoc") +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.linuxtools.lttng2.core.control.session.messages"; //$NON-NLS-1$ + + public static String SessionConfigXML_BadRequirementType; + public static String SessionConfigXML_DomainTypeMissing; + public static String SessionConfigXML_EventTypeMissing; + public static String SessionConfigXML_InvalidSessionInfoList; + public static String SessionConfigXML_InvalidTraceSessionPath; + public static String SessionConfigXML_UnknownEventType; + public static String SessionConfigXML_UnknownDomainBufferType; + public static String SessionConfigXML_SessionConfigGenerationError; + public static String SessionConfigXML_XmlParseError; + public static String SessionConfigXML_XmlValidateError; + public static String SessionConfigXML_XmlValidationError; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/SessionConfigGenerator.java b/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/SessionConfigGenerator.java new file mode 100644 index 0000000000..692862eb36 --- /dev/null +++ b/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/SessionConfigGenerator.java @@ -0,0 +1,539 @@ +/********************************************************************** + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Guilliano Molaire - Initial API and implementation + *********************************************************************/ +package org.eclipse.linuxtools.lttng2.core.session; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.Set; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.linuxtools.internal.lttng2.core.Activator; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.IChannelInfo; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.IDomainInfo; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.IEventInfo; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.ISessionInfo; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.TraceEnablement; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.TraceEventType; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.TraceLogLevel; +import org.eclipse.linuxtools.internal.lttng2.core.control.model.TraceSessionState; +import org.eclipse.osgi.util.NLS; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Class for generating a session configuration file. A session configuration is + * used to configure a trace session. It is a XML formatted file that contains + * values defining the behavior of that specific trace session. + * <p> + * Kernel session configuration example: + * + * <pre> + * {@code + * <sessions> + * <session> + * <name>test_kernel</name> + * <domains> + * <domain> + * <type>KERNEL</type> + * <buffer_type>GLOBAL</buffer_type> + * <channels> + * <channel> + * <name>channel0</name> + * <enabled>false</enabled> + * <overwrite_mode>DISCARD</overwrite_mode> + * <subbuffer_size>262144</subbuffer_size> + * <subbuffer_count>4</subbuffer_count> + * <switch_timer_interval>0</switch_timer_interval> + * <read_timer_interval>200000</read_timer_interval> + * <output_type>SPLICE</output_type> + * <tracefile_size>0</tracefile_size> + * <tracefile_count>0</tracefile_count> + * <live_timer_interval>0</live_timer_interval> + * <events> + * <event> + * <enabled>true</enabled> + * <type>SYSCALL</type> + * </event> + * <event> + * <name>snd_soc_cache_sync</name> + * <enabled>true</enabled> + * <type>TRACEPOINT</type> + * </event> + * </events> + * </channel> + * </channels> + * </domain> + * </domains> + * <started>false</started> + * <output> + * <consumer_output> + * <enabled>true</enabled> + * <destination> + * <path>/home/user/lttng-traces/test_kernel</path> + * </destination> + * </consumer_output> + * </output> + * </session> + * </sessions> + * } + * </pre> + * + * </p> + * + * @author Guilliano Molaire + * @since 3.0 + */ +public final class SessionConfigGenerator { + + /** The name of the session schema */ + private static final String SESSION_XSD_FILENAME = "session.xsd"; //$NON-NLS-1$ + + /** The indent size used for the session configuration XML file */ + private static final String INDENT_AMOUNT_PROPERTY_NAME = "{http://xml.apache.org/xslt}indent-amount"; //$NON-NLS-1$ + private static final String INDENT_AMOUNT_PROPERTY_VALUE = "4"; //$NON-NLS-1$ + + /** + * Private constructor. The class should not be instantiated. + */ + private SessionConfigGenerator() { + } + + // --------------------------------------------------------- + // Methods to generate session configuration files + // --------------------------------------------------------- + + /** + * Generates a session configuration file from a set of session information. + * + * @param sessions + * The session informations + * @param sessionFileDestination + * The path of the locally saved session configuration file + * @return The status of the session configuration generation + */ + public static IStatus generateSessionConfig(Set<ISessionInfo> sessions, IPath sessionFileDestination) { + /* Parameters validation */ + if (sessions == null || sessions.isEmpty()) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SessionConfigXML_InvalidSessionInfoList); + } else if (sessionFileDestination == null) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SessionConfigXML_InvalidTraceSessionPath); + } + + /* Generate the session configuration file */ + try { + Document sessionConfigDocument = generateSessionConfig(sessions); + + if (sessionConfigDocument != null) { + saveSessionConfig(sessionConfigDocument, sessionFileDestination.toString()); + } else { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SessionConfigXML_SessionConfigGenerationError); + } + } catch (TransformerException | IllegalArgumentException | ParserConfigurationException e) { + Activator.getDefault().logError("Error generating the session configuration file: " + sessionFileDestination.toString(), e); //$NON-NLS-1$ + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage()); + } + + return Status.OK_STATUS; + } + + /** + * Generates a session configuration from a set of session informations. + * + * @param sessions + * The session informations + * @return The document with all session configuration nodes + * @throws IllegalArgumentException + * On an illegal argument inside sessions + * @throws ParserConfigurationException + * On an parser configuration error + */ + private static Document generateSessionConfig(Iterable<ISessionInfo> sessions) throws IllegalArgumentException, ParserConfigurationException { + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + + Document document = docBuilder.newDocument(); + + Element rootElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_SESSIONS); + document.appendChild(rootElement); + + for (ISessionInfo session : sessions) { + /* All elements under "sessions" elements */ + Element sessionElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_SESSION); + + /* Contents of session element */ + String enabled = session.getSessionState().equals(TraceSessionState.ACTIVE) ? SessionConfigStrings.CONFIG_STRING_TRUE : SessionConfigStrings.CONFIG_STRING_FALSE; + + addElementContent(document, sessionElement, SessionConfigStrings.CONFIG_ELEMENT_NAME, session.getName()); + addElementContent(document, sessionElement, SessionConfigStrings.CONFIG_ELEMENT_STARTED, enabled); + + if (session.isSnapshotSession()) { + /* If it's a snapshot, we must add an attribute telling it is */ + Element attributesElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_ATTRIBUTES); + addElementContent(document, attributesElement, SessionConfigStrings.CONFIG_ELEMENT_SNAPSHOT_MODE, SessionConfigStrings.CONFIG_STRING_TRUE); + sessionElement.appendChild(attributesElement); + } + + sessionElement.appendChild(getDomainsElement(document, session)); + sessionElement.appendChild(getOutputElement(document, session)); + rootElement.appendChild(sessionElement); + } + + return document; + } + + // --------------------------------------------------------- + // Getters for each element of the configuration file + // --------------------------------------------------------- + + /** + * Gets the 'domains' element after creating it. + * + * @param document + * The document in which the nodes are being added + * @param session + * The session informations + * @return The domains element as an XML element + */ + private static Element getDomainsElement(Document document, ISessionInfo session) { + Element domainsElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_DOMAINS); + + for (IDomainInfo domain : session.getDomains()) { + Element domainElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_DOMAIN); + + /* + * Add everything specific to a domain + * + * TODO: We suppose here that domain is either kernel or UST. It + * will have to change if other domains are supported + */ + String domainType = domain.isKernel() ? SessionConfigStrings.CONFIG_DOMAIN_TYPE_KERNEL : SessionConfigStrings.CONFIG_DOMAIN_TYPE_UST; + addElementContent(document, domainElement, SessionConfigStrings.CONFIG_ELEMENT_TYPE, domainType); + + String bufferType = null; + switch (domain.getBufferType()) { + case BUFFER_PER_UID: + bufferType = SessionConfigStrings.CONFIG_BUFFER_TYPE_PER_UID; + break; + case BUFFER_PER_PID: + bufferType = SessionConfigStrings.CONFIG_BUFFER_TYPE_PER_PID; + break; + case BUFFER_SHARED: + bufferType = SessionConfigStrings.CONFIG_BUFFER_TYPE_GLOBAL; + break; + case BUFFER_TYPE_UNKNOWN: + default: + throw new IllegalArgumentException(Messages.SessionConfigXML_UnknownDomainBufferType); + } + addElementContent(document, domainElement, SessionConfigStrings.CONFIG_ELEMENT_DOMAIN_BUFFER_TYPE, bufferType); + + /* Add the channels */ + domainElement.appendChild(getChannelsElement(document, domain.isKernel(), domain.getChannels())); + domainsElement.appendChild(domainElement); + } + + return domainsElement; + } + + /** + * Gets the 'output' element after creating it. If the session is a + * snapshot, it will be composed of a snapshot outputs element. Otherwise, + * it will contain the consumer output element. + * + * @param document + * The document in which the nodes are being added + * @param session + * The session informations + * @return The output element as an XML node + */ + private static Element getOutputElement(Document document, ISessionInfo session) { + Element outputElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_OUTPUT); + + if (session.isSnapshotSession()) { + outputElement.appendChild(getSnapshotOuputsElement(document, session)); + } else if (session.isStreamedTrace()) { + outputElement.appendChild(getNetOutputElement(document, session)); + } else { + outputElement.appendChild(getConsumerOutputElement(document, session)); + } + + return outputElement; + } + + /** + * Gets the 'channels' element after creating it. + * + * @param document + * The document in which the nodes are being added + * @param isKernel + * Is it a kernel domain type + * @param channels + * The channels to be added as elements + * @return The channels element as an XML element + */ + private static Element getChannelsElement(Document document, boolean isKernel, IChannelInfo[] channels) { + Element channelsElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_CHANNELS); + + for (IChannelInfo channel : channels) { + Element channelElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_CHANNEL); + + /* Add everything related to a channel */ + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_NAME, channel.getName()); + + String overwriteMode = channel.isOverwriteMode() ? SessionConfigStrings.CONFIG_OVERWRITE_MODE_OVERWRITE : SessionConfigStrings.CONFIG_OVERWRITE_MODE_DISCARD; + String enabled = channel.getState().equals(TraceEnablement.ENABLED) ? SessionConfigStrings.CONFIG_STRING_TRUE : SessionConfigStrings.CONFIG_STRING_FALSE; + + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_ENABLED, enabled); + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_OVERWRITE_MODE, overwriteMode); + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_SUBBUFFER_SIZE, channel.getSubBufferSize()); + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_SUBBUFFER_COUNT, channel.getNumberOfSubBuffers()); + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_SWITCH_TIMER_INTERVAL, channel.getSwitchTimer()); + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_READ_TIMER_INTERVAL, channel.getReadTimer()); + + String outputType = channel.getOutputType().startsWith(SessionConfigStrings.CONFIG_OUTPUT_TYPE_MMAP) ? + outputType = SessionConfigStrings.CONFIG_OUTPUT_TYPE_MMAP : SessionConfigStrings.CONFIG_OUTPUT_TYPE_SPLICE; + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_OUTPUT_TYPE, outputType); + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_TRACEFILE_SIZE, channel.getMaxSizeTraceFiles()); + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_TRACEFILE_COUNT, channel.getMaxNumberTraceFiles()); + + /* + * TODO: Replace the 0 value by the channel live timer property from + * SessionInfo once live session tracing is supported + */ + addElementContent(document, channelElement, SessionConfigStrings.CONFIG_ELEMENT_LIVE_TIMER_INTERVAL, SessionConfigStrings.CONFIG_STRING_ZERO); + + /* Add the events */ + channelElement.appendChild(getEventsElement(document, isKernel, channel.getEvents())); + channelsElement.appendChild(channelElement); + } + + return channelsElement; + } + + /** + * Gets the 'events' element after creating it. It is composed of the event + * informations from a list of IEventInfo. + * + * @param document + * The document in which the nodes are being added + * @param isKernel + * Is the domain type kernel + * @param events + * The event informations to be added + * @return An element containing all the event informations as XML elements + */ + private static Element getEventsElement(Document document, boolean isKernel, IEventInfo[] events) { + Element eventsElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_EVENTS); + + for (IEventInfo event : events) { + Element eventElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_EVENT); + + /* Enabled attribute */ + String enabled = event.getState().equals(TraceEnablement.ENABLED) ? SessionConfigStrings.CONFIG_STRING_TRUE : SessionConfigStrings.CONFIG_STRING_FALSE; + + /* Add the attributes to the event node */ + addElementContent(document, eventElement, SessionConfigStrings.CONFIG_ELEMENT_NAME, event.getName()); + addElementContent(document, eventElement, SessionConfigStrings.CONFIG_ELEMENT_ENABLED, enabled); + TraceEventType eventType = event.getEventType(); + if (!eventType.equals(TraceEventType.UNKNOWN)) { + addElementContent(document, eventElement, SessionConfigStrings.CONFIG_ELEMENT_TYPE, eventType.getInName().toUpperCase()); + } else { + throw new IllegalArgumentException(Messages.SessionConfigXML_UnknownEventType); + } + + /* Specific to UST session config: the log level */ + if (!isKernel && !event.getLogLevel().equals(TraceLogLevel.LEVEL_UNKNOWN)) { + addElementContent(document, eventElement, SessionConfigStrings.CONFIG_ELEMENT_LOGLEVEL, event.getLogLevel().ordinal()); + } + + /* Add the node to the parent node events */ + eventsElement.appendChild(eventElement); + } + + return eventsElement; + } + + /** + * Gets the 'consumer_output' element after creating it. + * + * @param document + * The document in which the nodes are being added + * @param session + * The session informations + * @return The consumer output element with his informations as XML elements + */ + private static Element getConsumerOutputElement(Document document, ISessionInfo session) { + Element consumerOutputElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_CONSUMER_OUTPUT); + Element destinationElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_DESTINATION); + + /* Value of consumer output element */ + addElementContent(document, consumerOutputElement, SessionConfigStrings.CONFIG_ELEMENT_ENABLED, SessionConfigStrings.CONFIG_STRING_TRUE); + + if (session.isStreamedTrace()) { + /* If it is a streamed session, add the net output element */ + destinationElement.appendChild(getNetOutputElement(document, session)); + } else { + addElementContent(document, destinationElement, SessionConfigStrings.CONFIG_ELEMENT_PATH, session.getSessionPath()); + } + + consumerOutputElement.appendChild(destinationElement); + return consumerOutputElement; + } + + /** + * Gets the 'net_output' element after creating it. It is composed of the + * control and data URIs. + * + * @param document + * The document in which the nodes are being added + * @param session + * The session informations + * @return The net output element + */ + private static Element getNetOutputElement(Document document, ISessionInfo session) { + Element netOutputElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_NET_OUTPUT); + + String networkUrl = session.getNetworkUrl(); + String controlUri = networkUrl == null ? session.getControlUrl() : networkUrl; + String dataUri = networkUrl == null ? session.getDataUrl() : networkUrl; + addElementContent(document, netOutputElement, SessionConfigStrings.CONFIG_ELEMENT_CONTROL_URI, controlUri); + addElementContent(document, netOutputElement, SessionConfigStrings.CONFIG_ELEMENT_DATA_URI, dataUri); + + return netOutputElement; + } + + /** + * Gets the 'snapshot_outputs' element after creating it. + * + * @param document + * The document in which the nodes are being added + * @param session + * The session informations + * @return The snapshot outputs element with snapshot informations as XML + * elements + */ + private static Element getSnapshotOuputsElement(Document document, ISessionInfo session) { + Element snapshotOutputsElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_SNAPSHOT_OUTPUTS); + Element outputElement = document.createElement(SessionConfigStrings.CONFIG_ELEMENT_OUTPUT); + + /* Add the name of the snapshot and the max size element */ + addElementContent(document, outputElement, SessionConfigStrings.CONFIG_ELEMENT_NAME, session.getSnapshotInfo().getName()); + + /* + * TODO: find the proper max size value of output element. For now it is + * set to the default 0 value which means unlimited for lttng. + */ + addElementContent(document, outputElement, SessionConfigStrings.CONFIG_ELEMENT_MAX_SIZE, SessionConfigStrings.CONFIG_STRING_ZERO); + outputElement.appendChild(getConsumerOutputElement(document, session)); + + snapshotOutputsElement.appendChild(outputElement); + return snapshotOutputsElement; + } + + // --------------------------------------------------------- + // Utilities + // --------------------------------------------------------- + + /** + * Validates the session configuration file against its schema. + * + * @param sessionFile + * The session configuration file + * @return The status of the validation + */ + public static IStatus sessionValidate(File sessionFile) { + URL url = SessionConfigGenerator.class.getResource(SESSION_XSD_FILENAME); + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Source xmlSource = new StreamSource(sessionFile); + + try { + Schema schema = schemaFactory.newSchema(url); + Validator validator = schema.newValidator(); + validator.validate(xmlSource); + } catch (SAXParseException e) { + String error = NLS.bind(Messages.SessionConfigXML_XmlParseError, e.getLineNumber(), e.getLocalizedMessage()); + Activator.getDefault().logError(error); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); + } catch (SAXException e) { + String error = NLS.bind(Messages.SessionConfigXML_XmlValidationError, e.getLocalizedMessage()); + Activator.getDefault().logError(error); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); + } catch (IOException e) { + String error = Messages.SessionConfigXML_XmlValidateError; + Activator.getDefault().logError("IO exception occurred", e); //$NON-NLS-1$ + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, error, e); + } + return Status.OK_STATUS; + } + + /** + * Saves the session configuration into a XML file. + * + * @param document + * The document representing the session configuration file + * @param destination + * The path of the locally saved session configuration file + * @throws TransformerException + * On an transformation process + */ + private static void saveSessionConfig(Document document, String destination) throws TransformerException { + /* Write the content into a XML file */ + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + transformer.setOutputProperty(INDENT_AMOUNT_PROPERTY_NAME, INDENT_AMOUNT_PROPERTY_VALUE); + + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(new File(destination)); + + transformer.transform(source, result); + } + + /** + * Adds to a parent node an element with his content. + * + * @param document + * The document in which the nodes are being added + * @param parent + * The parent node that contains the element and his content + * @param elementName + * The element container name + * @param elementContent + * The content itself + */ + private static void addElementContent(Document document, Element parent, String elementName, Object elementContent) { + Element contentElement = document.createElement(elementName); + contentElement.appendChild(document.createTextNode(elementContent.toString())); + parent.appendChild(contentElement); + } +} diff --git a/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/messages.properties b/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/messages.properties new file mode 100644 index 0000000000..c0d252d198 --- /dev/null +++ b/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/messages.properties @@ -0,0 +1,23 @@ +############################################################################### +# Copyright (c) 2014 École Polytechnique de Montréal +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Guilliano Molaire - Initial API and implementation +############################################################################### + +SessionConfigXML_BadRequirementType=The requirement type is not supported +SessionConfigXML_DomainTypeMissing=The domain requirement type is missing +SessionConfigXML_EventTypeMissing=The event requirement type is missing +SessionConfigXML_InvalidSessionInfoList=The list of session is empty or null +SessionConfigXML_InvalidTraceSessionPath=The trace session path is not valid +SessionConfigXML_UnknownEventType=The event type is not handled by the session configuration +SessionConfigXML_UnknownDomainBufferType=The domain buffer type is not handled by the session configuration +SessionConfigXML_SessionConfigGenerationError=An error occurred while generating the session configuration file +SessionConfigXML_XmlParseError=XML Parsing error at line {0}: {1} +SessionConfigXML_XmlValidateError=An error occurred while validating the XML file. +SessionConfigXML_XmlValidationError=Error validating XML file {0} diff --git a/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/session.xsd b/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/session.xsd new file mode 100644 index 0000000000..7c3e9d8fc6 --- /dev/null +++ b/lttng/org.eclipse.linuxtools.lttng2.core/src/org/eclipse/linuxtools/lttng2/core/session/session.xsd @@ -0,0 +1,295 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Copyright (c) 2014 - Jérémie Galarneau <jeremie.galarneau@efficios.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" +elementFormDefault="qualified" version="2.5"> + +<xs:simpleType name="name_type"> + <xs:restriction base="xs:string"> + <xs:maxLength value="255"/> + </xs:restriction> +</xs:simpleType> + +<xs:simpleType name="uint64_type"> + <xs:restriction base="xs:integer"> + <xs:minInclusive value="0"/> + <xs:maxInclusive value="18446744073709551615"/> + </xs:restriction> +</xs:simpleType> + +<xs:simpleType name="uint32_type"> + <xs:restriction base="xs:integer"> + <xs:minInclusive value="0"/> + <xs:maxInclusive value="4294967295"/> + </xs:restriction> +</xs:simpleType> + +<xs:simpleType name="channel_overwrite_mode_type"> + <xs:restriction base="xs:string"> + <xs:enumeration value="DISCARD"/> + <xs:enumeration value="OVERWRITE"/> + </xs:restriction> +</xs:simpleType> + +<!-- Maps to the lttng_event_output enum --> +<xs:simpleType name="event_output_type"> + <xs:restriction base="xs:string"> + <xs:enumeration value="SPLICE"/> + <xs:enumeration value="MMAP"/> + </xs:restriction> +</xs:simpleType> + +<!-- Maps to the lttng_loglevel_type enum --> +<xs:simpleType name="loglevel_type"> + <xs:restriction base="xs:string"> + <xs:enumeration value="ALL"/> + <xs:enumeration value="RANGE"/> + <xs:enumeration value="SINGLE"/> + </xs:restriction> +</xs:simpleType> + +<!-- Maps to the lttng_event_type enum --> +<xs:simpleType name="event_type_type"> + <xs:restriction base="xs:string"> + <xs:enumeration value="ALL"/> + <xs:enumeration value="TRACEPOINT"/> + <xs:enumeration value="PROBE"/> + <xs:enumeration value="FUNCTION"/> + <xs:enumeration value="FUNCTION_ENTRY"/> + <xs:enumeration value="NOOP"/> + <xs:enumeration value="SYSCALL"/> + <xs:enumeration value="KPROBE"/> + <xs:enumeration value="KRETPROBE"/> + </xs:restriction> +</xs:simpleType> + +<xs:complexType name="event_probe_attributes_type"> + <xs:all> + <xs:element name="symbol_name" type="name_type" minOccurs="0"/> + <xs:element name="address" type="uint64_type" minOccurs="0"/> + <xs:element name="offset" type="uint64_type" minOccurs="0"/> + </xs:all> +</xs:complexType> + +<xs:complexType name="event_ftrace_attributes_type"> + <xs:all> + <xs:element name="symbol_name" type="name_type"/> + </xs:all> +</xs:complexType> + +<xs:complexType name="event_attributes_type"> + <xs:choice> + <xs:element name="probe_attributes" type="event_probe_attributes_type"/> + <xs:element name="function_attributes" type="event_ftrace_attributes_type"/> + </xs:choice> +</xs:complexType> + +<xs:complexType name="event_exclusion_list_type"> + <xs:sequence> + <xs:element name="exclusion" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> +</xs:complexType> + +<xs:complexType name="event_type"> + <xs:all> + <xs:element name="name" type="name_type" minOccurs="0"/> + <xs:element name="enabled" type="xs:boolean" default="true" minOccurs="0"/> + <xs:element name="type" type="event_type_type" default="TRACEPOINT" minOccurs="0"/> + <xs:element name="loglevel_type" type="loglevel_type" default="ALL" minOccurs="0"/> + <xs:element name="loglevel" type="xs:int" default="-1" minOccurs="0"/> + <xs:element name="filter" type="xs:string" minOccurs="0"/> + <xs:element name="exclusions" type="event_exclusion_list_type" minOccurs="0"/> + <xs:element name="attributes" type="event_attributes_type" minOccurs="0"/> + </xs:all> +</xs:complexType> + +<xs:complexType name="event_list_type"> + <xs:sequence> + <xs:element name="event" type="event_type" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> +</xs:complexType> + +<xs:complexType name="event_perf_context_type"> + <xs:all> + <xs:element name="type" type="uint32_type"/> + <xs:element name="config" type="uint64_type"/> + <xs:element name="name" type="name_type"/> + </xs:all> +</xs:complexType> + +<!-- Maps to the lttng_event_context_type enum --> +<xs:simpleType name="event_context_type_type"> + <xs:restriction base="xs:string"> + <xs:enumeration value="PID"/> + <xs:enumeration value="PROCNAME"/> + <xs:enumeration value="PRIO"/> + <xs:enumeration value="NICE"/> + <xs:enumeration value="VPID"/> + <xs:enumeration value="TID"/> + <xs:enumeration value="VTID"/> + <xs:enumeration value="PPID"/> + <xs:enumeration value="VPPID"/> + <xs:enumeration value="PTHREAD_ID"/> + <xs:enumeration value="HOSTNAME"/> + <xs:enumeration value="IP"/> + </xs:restriction> +</xs:simpleType> + +<xs:complexType name="event_context_type"> + <xs:choice> + <xs:element name="type" type="event_context_type_type"/> + <xs:element name="perf" type="event_perf_context_type"/> + </xs:choice> +</xs:complexType> + +<xs:complexType name="event_context_list_type"> + <xs:sequence> + <xs:element name="context" type="event_context_type" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> +</xs:complexType> + +<!-- Maps to struct lttng_channel --> +<xs:complexType name="channel_type"> + <xs:all> + <xs:element name="name" type="name_type"/> + <xs:element name="enabled" type="xs:boolean" default="true" minOccurs="0"/> + <xs:element name="overwrite_mode" type="channel_overwrite_mode_type" default="DISCARD" minOccurs="0"/> + <xs:element name="subbuffer_size" type="uint64_type" minOccurs="0"/> <!-- bytes --> + <xs:element name="subbuffer_count" type="uint64_type" default="4" minOccurs="0"/> + <xs:element name="switch_timer_interval" type="uint32_type" default="0" minOccurs="0"/> <!-- usec --> + <xs:element name="read_timer_interval" type="uint32_type"/> <!-- usec --> + <xs:element name="output_type" type="event_output_type"/> + <xs:element name="tracefile_size" type="uint64_type" default="0" minOccurs="0"/> <!-- bytes --> + <xs:element name="tracefile_count" type="uint64_type" default="0" minOccurs="0"/> + <xs:element name="live_timer_interval" type="uint32_type" default="0" minOccurs="0"/> <!-- usec --> + <xs:element name="events" type="event_list_type" minOccurs="0"/> + <xs:element name="contexts" type="event_context_list_type" minOccurs="0"/> + </xs:all> +</xs:complexType> + +<!-- Maps to the lttng_domain_type enum --> +<xs:simpleType name="domain_type_type"> + <xs:restriction base="xs:string"> + <xs:enumeration value="KERNEL"/> + <xs:enumeration value="UST"/> + <xs:enumeration value="JUL"/> + </xs:restriction> +</xs:simpleType> + +<!-- Maps to the lttng_buffer_type enum --> +<xs:simpleType name="domain_buffer_type"> + <xs:restriction base="xs:string"> + <xs:enumeration value="PER_PID"/> + <xs:enumeration value="PER_UID"/> + <xs:enumeration value="GLOBAL"/> + </xs:restriction> +</xs:simpleType> + +<xs:complexType name="channel_list_type"> + <xs:sequence> + <xs:element name="channel" type="channel_type" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> +</xs:complexType> + +<!-- Maps to struct lttng_domain and contains channels --> +<xs:complexType name="domain_type"> + <xs:all> + <xs:element name="type" type="domain_type_type"/> + <xs:element name="buffer_type" type="domain_buffer_type"/> + <xs:element name="channels" type="channel_list_type" minOccurs="0"/> + </xs:all> +</xs:complexType> + +<xs:complexType name="session_attributes_type"> + <xs:choice> + <xs:element name="snapshot_mode" type="xs:boolean"/> + <xs:element name="live_timer_interval" type="uint32_type"/> <!-- usec --> + </xs:choice> +</xs:complexType> + +<xs:complexType name="domain_list_type"> + <xs:sequence> + <xs:element name="domain" type="domain_type" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> +</xs:complexType> + +<xs:complexType name="net_output_type"> + <xs:all> + <xs:element name="control_uri" type="xs:string"/> + <xs:element name="data_uri" type="xs:string"/> + </xs:all> +</xs:complexType> + +<xs:complexType name="destination_type"> + <xs:choice> + <xs:element name="path" type="xs:string"/> + <xs:element name="net_output" type="net_output_type"/> + </xs:choice> +</xs:complexType> + +<xs:complexType name="consumer_output_type"> + <xs:all> + <xs:element name="enabled" type="xs:boolean" default="true"/> + <xs:element name="destination" type="destination_type"/> + </xs:all> +</xs:complexType> + +<xs:complexType name="snapshot_output_type"> + <xs:all> + <xs:element name="name" type="name_type"/> + <xs:element name="max_size" type="uint64_type"/> + <xs:element name="consumer_output" type="consumer_output_type"/> + </xs:all> +</xs:complexType> + +<xs:complexType name="snapshot_output_list_type"> + <xs:sequence> + <xs:element name="output" type="snapshot_output_type" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> +</xs:complexType> + +<xs:complexType name="session_output_type"> + <xs:choice> + <xs:element name="snapshot_outputs" type="snapshot_output_list_type"/> + <xs:element name="consumer_output" type="consumer_output_type"/> + </xs:choice> +</xs:complexType> + +<xs:complexType name="session_type"> + <xs:all> + <xs:element name="name" type="name_type"/> + <xs:element name="domains" type="domain_list_type" minOccurs="0"/> + <xs:element name="started" type="xs:boolean" default="0" minOccurs="0"/> + <xs:element name="attributes" type="session_attributes_type" minOccurs="0"/> + <xs:element name="output" type="session_output_type" minOccurs="0"/> + </xs:all> +</xs:complexType> + +<xs:element name="sessions"> + <xs:complexType> + <xs:sequence> + <xs:element name="session" type="session_type" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> +</xs:element> + +</xs:schema> |