Release 0.10.3, December 2019
1. Variant Server Installation
Variant server is entirely self-contained and does not have any external dependencies. It requires Java runtime 8 or later. To install Variant server:
- Download Variant Server distribution.
- Unpack the distribution in a directory of your choice by running
$ unzip /path/to/variant-server-<release>.zip
This will create a server installation with the following directory structure:
Directory | Description |
---|---|
bin/ | Contains the server startup shell script variant.sh along with dependent scripts which you should never have to use. |
conf/ | Configuration directory, containing the server config file variant.conf , logging config file logback.xml , and other dependent configuration artifacts. |
lib/ | System libraries. |
ext/ | User extensions, developed on top of the Extension API, and their dependencies. The distribution contains the the standard extension library variant-extapi-standard-<release>.jar . All JAR files in the ext/ directory are added to Variant server’s runtime classpath. |
log/ | Default destination for the server log files. |
schemata/ | Default location of the variation schema files. The distribution contains the example.schema file. |
- Change directory to Variant server top level directory:
$ cd variant-server-<release>
- Start Variant server in the foreground:
$ bin/variant.sh start
If all goes well, the server console output should look something like this:
$ bin/variant.sh start
2019-12-10 09:54:44,477 INFO - c.v.s.boot.ConfigLoader$ - Found config resource [/variant.conf] as [/Users/Igor/soft/variant-server-0.10.2/conf/variant.conf]
2019-12-10 09:54:45,285 INFO - c.v.s.schema.SchemaDeployerFileSystem - Mounted schemata directory [/Users/Igor/soft/variant-server-0.10.2/schemata]
2019-12-10 09:54:45,287 INFO - c.v.s.schema.SchemaDeployerFileSystem - [421] Deploying schema from file [/Users/Igor/soft/variant-server-0.10.2/schemata/example.schema]
2019-12-10 09:54:45,490 INFO - c.v.s.schema.Schemata - [422] Deployed schema [exampleSchema] from file [example.schema]
2019-12-10 09:54:45,494 INFO - c.v.s.boot.VariantServerImpl - [433] Variant CVM Server release 0.10.2 started on port [5377] in 2.131s
At this point, the server is ready to deploy variation schema files, which you copy into the schemata/
directory.
By default, the server attaches to port 5377. To start the server on a different port, pass the port number in the variant.http.port
on the startup command line. For example, to start on port 9999:
$ bin/variant.sh start -Dvariant.http.port=9999
You may always ping a running server by typing its URL into a Web browser, or with the curl
command:
$ curl localhost:5377
{
"name" : "Variant CVM Server",
"version" : "0.10.3",
"uptimeSeconds" : 6,
"build" : {
"timestamp" : "2019-12-22T20:02:10.937Z",
"scalaVersion" : "2.12.7",
"javaVersion" : "1.8.0_191",
"javaVmName" : "Java HotSpot(TM) 64-Bit Server VM",
"javaVmVersion" : "25.191-b12"
},
"schemata" : [ {
"name" : "example",
"comment" : "Basic sample variation schema. See User Guide for details."
} ]
}
A running server can be stopped by typing Control-C
in the shell where it was started, or by typing in a different shell window
$ bin/variant.sh stop
2. Variant Server Configuration
2.1. Sources Of Configuration
Variant server is configured via configuration properties organized in conf files. At startup, Variant server looks for configuration in the file conf/variant.conf
. If it is found, its contents override the default settings, listed in the next section. If you need to modify any configuration properties, you may either update them directly in the conf/variant.conf
file, or provide an alternate configuration file whose contents take precedence over those of the conf/variant.conf
file.
The alternate config file may be provided on the command line either as a file system file:
$ variant.sh start -Dvariant.config.file=/path/to/alt/config/as/file
or as a Java classpath resource:
$ variant.sh start -Dvariant.config.resource=resource-name
The simplest way to add a resource to the server classpath is to place it in the server’s conf
directory, which is added to the server’s runtime classpath at the root level. In other words, the file conf/extra.conf
should be referenced as
$ variant.sh start -Dvariant.config.resource=/extra.conf
It is an error to set both variant.config.file
and variant.config.resource
system properties.
Finally, each individual config parameter may be overridden from the command line via the JVM system variable of the same name, e.g.:
$ variant.sh start -Dvariant.schemata.dir=/Users/Igor/schemata
2.2. Variant Server Configuration Properties
The following table lists all config properties recognized by Variant server.
Property | Default Value / Description |
---|---|
variant.event.flusher.class.name | com.variant.server.api.EventFlusherAppLogger Default event flusher implementation, implicitly provided to those variation schemata that do not define their own. |
variant.event.flusher.class.init | null Arbitrary JSON object, whose parsed representation will be passed to the constructor of the event flusher implementation. Not required by the default com.variant.server.api.EventFlusherAppLogger above. |
variant.event.writer.flush.buffers | [10,20] Min and max number of flush buffers in the event writer buffer cache. The first value is the number of buffers which will be always kept around even if fewer would suffice to keep up with the trace event production rate. Whenever event writer requires more flush buffers than is currently allocated (due to an increased rate of production or deployment of new schema(ta)) additional buffers will be allocated up to the second number. Whenever the demand for flush buffers drops, additional flush buffers will be deallocated until the total number of buffers reaches the first number again. The second value must be >= the first value. |
variant.event.writer.flush.buffer.size | 500 Number of trace events each event buffer can hold. |
variant.event.writer.max.delay | 30 Maximum delay in seconds between the time when a trace event is triggered and the time it is passed to an event flusher. This ensures that events triggered by a low-traffic schema and not stuck in the asynchronous event writer for exessively long periods of time. |
variant.event.writer.flush.pool.size | Twice the number of available cores. The size of the flush thread pool. Event writer schedules calls to the flush() methods to be executed concurrently in a dedicated thread pool of this size. Buffers are flushed in the order they fill up. The flush pool is shared between all schemata. |
variant.http.port | 5377 Variant server HTTP port. |
variant.https.port | 5378 Variant server HTTPS port. |
variant.schemata.dir | "schemata" The directory where Variant server looks for variation schemata, as an OS file name. If starts with a slash, interpreted as an absolute path. Otherwise, as relative path to the server startup directory. |
variant.session.timeout | 900 Session timeout. User sessions are expired after this many seconds of inactivity. |
variant.session.vacuum.interval | 10 The session vacuum thread is woken up no less frequently than this many seconds. |
3. Variation Schema Grammar
Variant manages code variation metadata in human readable files, called schema files. Each schema file contains a single code variation schema describing a set of related code variations instrumented on some host application using the familiar YAML syntax. Keys (the strings to the left of the :
) are the reserved keywords that have a specific meaning. Keywords are case-insensitive, e.g. 'name:'
, 'Name:'
, or 'NAME:'
are interhcangeable.
The rest of this chapter provides detailed information on the schema grammar. The following conventions are used throughout the chapter:
any-string | Arbitrary, case sensitive, Unicode string. Follow YAML’s escape rules if you want a string contain special characters. |
name-string | Case insensitive, quoted string containing only Unicode letters, digits or the ‘_’ (underscore) and not starting with a digit. For example, _mySchema is a valid name and is indistinguishible from, e.g. _MYSCHEMA , but 3rdField is not a valid name. |
boolean | YAML Boolean value of true or false . |
number | YAML numeric value. Numbers without a decimal point will be converted to a 32-bit signed integer. Numbers containing a decimal point will be converted to a 64 bit double. |
literal | Arbitrary YAML literal. This may be a primitive type, an object, or an array. |
{type} | YAML mapping (dictionary) literal of a given type. |
[type] | YAML sequence of mappings of a given type. |
key?: | Optional key. |
3.1. General Structure
A variation schema is a dictionary with the following structure:
schema-spec :=
name: name-string
description?: any-string
states: [state-spec]
variations: [variation-spec]
flusher?: <flusher-spec>
hooks?: [hook-spec]
Listing 1. Top-level structure of a variation schema config.
Property | Type | Description | Required | Default |
---|---|---|---|---|
name | name-string | The name by which this schema will be connected to by clients. | Yes | |
description | any-string | A comment about this schema. | No | None |
flusher | Mapping of type flusher-spec | An event flusher specification defines a schema-specific trace event flusher. Applies to all trace events generated by the variations configured by this schema. | No | As configured by the server config properties. |
hooks | Sequence of mappings of type hook-spec | A list of schema-scoped lifecycle hook specifications. Hooks defined at this scope apply to all states and all variations defined by this schema. | No | |
states | Sequence of mappings of type state-spec . | A list of state specifications. | Yes | |
variations | Sequence of mappings of type variation-spec . | A list of variation specifications. | Yes |
3.2. Trace Even Flusher
Each Variant schema gets its own instance of an event flusher, shared by all variations. Flusher is instantiated by Variant server at schema deployment time. The Java class referenced by the class
property must be on the server’s class path. You may pass arbitrary state data to this instance by supplying the init
property, which must be a string. If no init string is given, the flusher will be instantiated with a public nullary constructor. If an init string is given, it will be passed to the public unary constructor which takes a single parameter of type String
. The appropriate constructor must be provided by the implementing class.
flusher-spec :=
name?: name-string
class: any-string
init?: any-string
Property | Type | Description | Required | Default |
---|---|---|---|---|
name | name-string | The name by which this flusher will be referenced in system messages. | No | The short name of the class. |
class | any-string | Fully qualified name of the implementing class. | Yes | |
init | any-string | Flusher’s initial state, passed to its constructor. | No | None |
For more information, see Section 4.2 Event Flushers.
3.3. Lifecycle Hooks
Lifecycle hooks are custom callbacks that can be defined at the schema, state, or variation scope. Each hook listens to a particular lifecycle event, such as VariationQualificationLifecycleEvent
. Whenever the event is raised, Variant posts all qualifying hooks in a predictable order. For more information, see Section 4.1 Lifecycle Hooks.
The Java class referenced by the class
property must be on the server’s class path. You may pass arbitrary state data to this instance by supplying the init
property, which must be a string. If no init string is given, the hook will be instantiated with a public nullary constructor. If an init string is given, it will be passed to the public unary constructor which takes a single parameter of type String
. The appropriate constructor must be provided by the implementing class.
hook-spec :=
name?: name-string
class: any-string
init?: any-string
Property | Type | Description | Required | Default |
---|---|---|---|---|
name | name-string | The name of the hook. Must be unique within current scope. | No | Short name of the class. |
class | any-string | Fully qualified name of the implementing class. | Yes | |
init | any-string | Hook’s initial state, passed to its constructor. | No | None. |
3.4. SATES
Mapping
In the Code Variation Model, a state represents an interface state of the host application where it pauses for user input. CVM states are rather abstract: the only required property is name
, by which the state can be referenced. States form a set, not a graph, i.e. user sessions traverse states one at a time, but there is no predefined order in which these states can be visited or which states are accessible from any particular state.
state-spec :=
name: name-string
parameters?: <state-parameter-spec>
hooks: [hook-spec]
Property | Type | Description | Required | Default |
---|---|---|---|---|
name | name-string | The name of the state. Must be unique within a schema. | Yes | |
parameters | An mapping of type state-parameter-spec | Each field in the object represents a state parameter. | No | None |
hooks | Array of objects of type hook-spec | A list of state-scoped lifecycle hook specifications. Hooks defined at this scope apply to this state only and must be subscribed to a lifecycle event descendant from StateAwareLifecycleEvent . | No | None |
3.5. State Parameters
Although CVM is agnostic of the host application’s technology stack, it provides a mechanism for the test designer to attach application-specific context to states in the form of state parameters. The host application can access this externalized state at run time. State parameters can be specified either at the state level, as explained in the previous section, or at the state variant level, as explained later in Section 3.7.3. Each state parameter is a key/value pair, where both the key and the value are strings.
state-parameter-spec :=
any-string: any-string
...
Property | Type | Description | Required | Default |
---|---|---|---|---|
Parameter’s name | any-string | Parameter’s name is an any-string that is a valid YAML key. Any number of parameters can be specified. | Yes | |
Parameter’s value. | any-string | Parameter’s value is any-string . | Yes |
Whenever the host application calls the Session.targetForState()
method, server picks from the given state’s variant space a single state variant. The state parameters defined at that state variant, if any, override the like-named parameters defined at the base state. (Remember, names are case sensitive.) These resolved state parameters are available to the host application via the StateRequest.getResolvedParameters()
method.
3.6. VARIATIONS
Mapping
3.6.1. Code Variations
A code variation or just variation is is a point code-path bifurcation, where the actual code path is determined dynamically at runtime. Variations are instrumented over one or more states and contain two or more experiences. Each variation must define exactly one control experience (the one mapped to the current code path) and one or more variant experiences, mapped to the candidate code path(s).
variation-spec :=
name: name-string
isOn?: boolean
durability?: durability-spec
experiences: [experience-spec]
concurrentVariations: [name-string]
onStates: [on-state-spec]
hooks?: [hook-spec]
Property | Type | Required | Default |
---|---|---|---|
name | name-string | Yes | |
isOn | boolean | No | true |
durability | An mapping of type durability-spec | No | Session durability for both qualification and targeting. |
experiences | Sequence of mappings of type experience-spec | Yes | |
concurrentVariations | Sequence of name-string s. | No | — |
onStates | Sequence of mappings of type on-state-spec | Yes | |
hooks | Sequence of mappings of type hook-spec | No | — |
For each state on the onStates
list, Variant builds a state variant space as a Cartesian product of this variation’s experience set and the experience sets of all those variations mentioned on the conjointVariations
list. Refer to Variant Server User Guide for more information on concurrent variations.
Each variation-scoped hook must listen to a lifecycle event descendant from VariationAwareLifecycleEvent
. For more information, see Section 4.1 Lifecycle Hooks.
The isOn
property is used to turn an experiment or a feature toggle temporarily offline without removing it from the schema. No sessions are targeted for an offline variation, as if it didn’t even exist. In fact, the only differences between an offline variation and a variation that is completely removed from the schema is that if it defines its targeting or qualification persistence as durable, this information is preserved. In practice this means that, after an offline variation is taken back online, return users will see the same experience they saw before the variation was taken offline.
3.6.2. Variation Durability
Variation durability determines the degree of persistence of qualification and targeting decisions with respect to the given variation.
durability-spec :=
qualification: state|session|variation
targeting: state|session|variation
3.6.3. Variation Experiences
Each element of a variation’s experiences
property describes one of its experiences.
experience-spec :=
name: name-string
weight: number
isControl?: boolean
Property | Type | Description | Required | Default |
---|---|---|---|---|
name | name-string | The name of the experience. Must be unique within enclosing variation. | Yes | |
weight | number | The probabilistic weight of this experience relative to other experiences of this variation. Used by the default targeting hook, which targets sessions randomly, according to these weights. The probability that a session is targeted to an experience is the ratio of the weight of the experience to the sum of weights of all of the variation’s experiences. | No | 1 |
isControl | boolean | Indicates whether this experience is the control experience in the enclosing variation. Exactly one experience must be marked as control. | No | false |
Listing 8. The schema definition of a test experience.
3.6.4. Variation On-States
The onStates
property contains a list of elements, each of which describes the enclosing variation’s instrumentation details on a particular state.
on-state-spec :=
state: name-string
experiences?: [name-string]
variants?: [state-variant-spec]
Listing 9 The schema definition of an onState property.
Property | Type | Description | Required | Default |
---|---|---|---|---|
state | name-string | Back reference to a state that’s already been defined, whose instrumentation by the enclosing test is defined by this property. | Yes | |
experiences | Array of name-string s. | This variation’s experiences that are instrumented on this state. | No | List of this state’s experiences. |
varaints | Array of objects of type state-variant-spec | A list of this state’s variant specifications. | No | — |
Whenever a variation V
instruments state S
, Variant schema parser creates the state variant space ν(V,S)
as a Cartesian product of the set of V
‘s experiences and the experience sets of all variations conjointly concurrent with V
. All state variants in ν(V,S)
implicitly inherit the state parameters as defined in the base state S
. In most cases, this inferred state variant space is sufficient, and you will only need to define state variants explicitly if you wish to override one or more state variants.
Implicitly inferred state variants inherit their state parameters from the base state. If you need to define variant-specific parameters, you must define them explicitly. Refer to Server User Guide for more information on state parameter inheritance.
3.6.5. State Variants
The variants
property contains a list of elements, each of which describes a particular state variant.
state-variant-spec :=
isPhantom?: boolean
experience: name-string
concurrentExperiences?:
- variation: name-string
experience: name-string
...
parameters: state-parameter-spec
Property | Type | Description | Required | Default |
---|---|---|---|---|
isPhantom | boolean | Indicates whether this state variant is phantom. If set to true , incompatible with any other property. | No | false |
experience | name-string | Reference to one of the enclosing variation’s own variant experiences. Cannot refer to the control experience. Not allowed in phantom state variants. | Yes | |
conjointExperiences | Array of objects. | Reference to one of the enclosing variation’s conjoint experiences. Not allowed in phantom state variants. | Yes | |
parameters | Array of objects of type state-parameter-spec . | A list of state parameter specifications. Not allowed in phantom state variants. | No | — |
Listing 10. The schema definition of a state variant.
A state variant is phantom in a particular experience if it is not instrumented by the experience. Phantom state variants possess the following semantics:
- When a session is targeted for a variation, phantom experiences are not considered.
- When a session requests a state which is phantom in a live experience, Variant will emit a runtime user error.
Refer to Variant Server User Guide for more information on mixed instrumentation.
4. Server Extension API
Variant server’s functionality can be extended through the use of the server-side Extension API, or ExtAPI, which exposes Java bindings for supplying custom server-side extensions. These extensions facilitate injection of custom semantics into the server’s default execution path via a callback mechanism. Two types of user-defined callback objects are supported:
- Lifecycle Event Hooks are listeners for various lifecycle events, raised by the server. They encapsulate custom, application-aware code, which takes over and alters the default handling of lifecycle events.
- Trace Event Flushers handle the final ingestion of trace events. Each variation schema can have its own event flusher.
Both lifecycle hooks and event flushers are configured in the variation schema. The next two chapters explain their semantics and configuration, and chapter 4.3 provides details on how to write them.
4.1. Lifecycle Hooks
4.1.1. Lifecycle Events
The following is the complete list of lifecycle events raised by Variant server:
Lifecycle Event | Event Scope | Default Hook |
---|---|---|
VariationQualificationLifecycleEvent | Schema Variation | Session is qualified for the variation. |
Raised when a Variant session must be qualified for a variation. Posts all eligible schema-scoped hooks and those variation-scoped hooks whose variation matches that of triggering event. Used to qualify (or disqualify) a user session for the triggering variation, based on a custom qualification criteria. | ||
VariationTargetingLifecycleEvent | Schema State Variation | Variation is targeted randomly, according to the weight properties. |
Raised when a Variant session must be targeted for a variation. Posts all eligible schema-scoped hooks, those state-scoped hooks whose state matches that of triggering event, and those variation-scoped hooks whose variation matches that of the triggering event. Used to provide custom targeting algorithm. |
4.1.2. Hooks’ Instantiation and Scope
Lifecycle hooks provide callback methods which are posted by Variant server whenever a lifecycle event of interest is raised. A lifecycle hook subscribes to a particular lifecycle event type by implementing the LifecycleHook.gerLifecycleEventClass()
method. Whenever an event of that type is raised, the hook is notified by Variant server via its callback method LifecycleHook.post()
method.
Hook definitions may appear in variation schema in one of three scopes:
- Meta-scoped hooks are defined inside the meta section. These hooks are applicable to all states and all variations in the schema. Hooks listening to lifecycle events descendant from
StateAwareLifecycleEvent
will be posted for each state in the schema by every state aware lifecycle event. Hooks listening to lifecycle events descendant fromVariationAwareLifecycleEvent
will be posted for all online variations in the schema by every variation aware lifecycle event. - State-scoped hooks are defined inside the state definition. These hooks are applicable to the enclosing state only and must listen to events descendant from
StateAwareLifecycleEvent
. - Variation-scoped hooks are defined inside the variation definition. These hooks are applicable to the enclosing variation only and must listen to events descendant from
VariationAwareLifecycleEvent
.
4.1.3. Hook Chaining
In any scope, any number of hooks can be defined. If more than one lifecycle hook is eligible to be posted by a lifecycle event at runtime, they form a hook chain.
A hook chain is posted in the following order:
- Variation-scoped hooks, then state-scoped hooks, then schema-scoped hooks.
- Within a scope, hooks are posted in the ordinal order, i.e. the order in which they are defined in the schema, in the corresponding scope.
The hooks are posted serially, until a hook’s post()
method returns a non-empty Optional
. If no custom hooks have been defined for a lifecycle event, or all returned an empty Optional
, the default built-in hook for the event is posted, which is guaranteed to return a usable value.
A hook chain is posted synchronously; the hooks’ post()
methods are invoked one at a time while the foreground user session thread is blocked. Conequently, the post()
method need not be thread safe. A new instance of a hook is instantiated for each invocation of the post()
method.
When a hook is posted, its post(E event)
method is called by Variant server with the actual triggering lifecycle event instance. If the post(E event)
method returns a non-null value, Variant server ignores the rest of the hook chain, expecting the returned object to contain the information it requires to proceed. Otherwise, Variant posts the next hook on the chain.
4.1.4. Custom Lifecycle Hooks
A custom lifecycle hook must implement the LifecycleHook
interface. By contract, an implementation must also provide at least one of these constructors:
- Nullary constructor, if no
init
property was given in the hook definition. - Single argument constructor with argument type Config . If no
init
property was given and no nullary constructor is available, this constructor will be called withnull
argument; otherwise, the value of theinit
property will be parsed and passed to this constructor.
Refer to Section 4.3 for packaging details.
4.2. Trace Event Flushers
Trace events are generated by user traffic, as it flows through Variant variations. Event flushers handle the terminal ingestion of these events with the purpose of subsequent analysis by a downstream process. Trace events can be triggered implicitly, by Variant, or explicitly by the host application. In either case, the host application can attach attributes to these events, to aid in the downstream analysis.
Variant server automatically enriches all trace events with the following metadata:
- Variant session ID by which related events can be associated.
- Names of sessions’s live experiences.
- Custom event attributes.
A typical event flusher writes trace events to a persistent storage mechanism, such as an external database or event stream. Whenever a trace event is triggered — implicitly by Variant server or explicitly by user code — it is picked up by the Variant’s asynchronous event writer, where it is held in a memory buffer until a dedicated flusher thread becomes available. There is one event writer per Variant server, shared by all schemata. Event writer groups trace events by the schema that produced them and turns them over to the apropriate event flusher by calling its flush()
method.
Each call to the flush()
method is scheduled to be executed asynchronously and, potentially concurrently with other similar calls, by a dedicated thread pool, whose size is configured by the variant.event.writer.buffer.flush.pool.size
config property. Buffers are passed to the thread pool as soon as they fill up or the variant.event.writer.max.delay
number of seconds has elapsed since the time when the oldest event in the buffer was triggered.
Note, that it is possible that the same flusher instance is accessed by multiple threads, so it is critical that the flush()
method you write be thread safe. In particular, avoid mutable instance state in custom event flushers.
Trace event flushers are configured in the META
section of the variation schema, as in the following example:
{
'meta':{
'name':'petclinic',
'comment':'Variant schema for the Pet Clinic demo application',
'flusher': {
'class':'com.variant.extapi.std.flush.TraceEventFlusherCsv',
'init':{'header':true, 'file':'/tmp/variant-trace-events-petclinic.csv'}
}
},
'states':[...],
'variations':[...],
}
If no event flusher is configured in the schema, the system wide default is assumed, as configured by the variant.event.flusher.class.*
properties.
A number of pre-built trace event flushers come with the server, as part of the standard extension library, discussed in Section 4.4.
4.3. Developing for the ExtAPI
Variant server extension API library variant-server-extapi-<release>.jar
can be downloaded from the Variant website. Create a new Java project in your IDE, add this JAR file to the classpath and you are set. You must package your project as JAR. To add the packaged JAR file to Variant server’s runtime classpath, copy it (and its dependencies) into the server’s ext/
directory.
Alternatively, but with the same ultimate result, — you may clone the standard extension public repository into a local workspace, remove the source files, change the groupId, artifactId and the version to suit your environment,— and you have a working shell of a brand new ExtAPI development project.
Note, that a running Variant server loads all hook and flusher classes from the class path only once, when they are first encountered. Therefore, replacing classes in the server’s ext/
directory will not have any effect and may even lead to unexpected behavior. Always restart your Variant server when you redeploy your custom ExtAPI classes.
4.4. The Standard Extension Library
Variant server standard extension is a library of general purpose extensions, written on top of the ExtAPI. They provide out-of-the-box functionality which is not part of the core Variant server. They are packaged as variant-extapi-standard-<release>.jar
file wich is incliuded in the server distribution in the ext/
directory.
The standard extension library is an open source project, available on GitHub under the Apache 2 license. You may find it useful to examine the source code, before developing your own custom lifecyle event hooks and trace event flushers.
4.4.1. Package com.variant.extapi.std.demo
Contains the UserQualifyingHook
lifecycle hook, required by the Servlet Demo Application .
4.4.2. Package com.variant.extapi.std.fush
Contains the folloiwng ready to use trace event flushers:
TraceEventFlusherNull |
---|
Discards all trace events. Configuration: None. Example:‘flusher’: { ‘class’:’com.variant.extapi.std.flush.TraceEventFlusherNull’ } |
TraceEventFlusherServerLog |
Appends trace events to the application logger. This is the default, out of the box event flusher, which is completely independent of the operational environment. Probably not for production use. Configuration: level – specifies the logging level to be used. Defaults to ‘INFO’. Example:‘flusher’: { ‘class’:’com.variant.extapi.std.flush.TraceEventFlusherApplicationLog’, ‘init’:{‘init’:”info”} } |
TraceEventFlusherCsv |
Writes trace events to a local CSV file. The output file format conforms to the IETF RFC4180 specification. Configuration: header – boolean – Wether or not to include the metadata header as very first line. The default is false. file – string – The name of the file to write to. Will be overwritten if exists. The default is “variant-events.csv” Example:‘flusher’: { ‘class’:’com.variant.extapi.std.flush.TraceEventFlusherCsv’, ‘init’:{‘file’:’/tmp/variant-events.csv’,’header’:true} } |
jdbc/TraceEventFlusherH2 |
Writes Variant events to an H2 database. The SQL scripts required to create the database schema expected by this flusher can be found in db/h2 directory. You must also copy the H2 JDBC driver into Variant server’s ext/ directory. Configuration: url – string – The URL to the H2 database instance. user – string – The database user name. password – string – The database user’s password. Example:‘flusher’: { ‘class’:’com.variant.extapi.std.flush.jdbc.TraceEventFlusherH2′, ‘init’:{ ‘url’:”jdbc:h2:mem:variant;MVCC=true;DB_CLOSE_DELAY=-1;’, ‘user’:’variant’, ‘password”:’variant’} } |
jdbc/TraceEventFlusherMysql |
Writes Variant events to a MySQL database. The SQL scripts required to create the database schema expected by this flusher can be found in db/mysql directory. You must also copy the MySQL JDBC driver into Variant server’s ext/ directory. Configuration: url – string – The URL to the MySQL database instance. user – string – The database user name. password – string – The database user’s password. Example:‘flusher’: { ‘class’:’com.variant.extapi.std.flush.jdbc.TraceEventFlusherMysql’, ‘init’:{ ‘url’:”jdbc:mysql://localhost/variant’, ‘user’:’variant’, ‘password”:’variant’} } |
jdbc/TraceEventFlusherPostgres |
Writes Variant events to a PostgreSQL database. The SQL scripts required to create the database schema expected by this flusher can be found in db/postgres directory. You must also copy the Postgres JDBC driver into Variant server’s ext/ directory. Configuration: url – string – The URL to the PostgreSQL database instance. user – string – The database user name. password – string – The database user’s password. Example:‘flusher’: { ‘class’:’com.variant.extapi.std.flush.jdbc.TraceEventFlusherPostgres’, ‘init’:{ ‘url’:”jdbc:postgresql://localhost/variant’, ‘user’:’variant’, ‘password”:’variant’} } |