Skip to main content

Events raised by a legacy agent

BETA Preview

This feature is still being finalized by Development.

See Relays, Agents and agent pools and Event log.

A job — or any process — running on a legacy LSAM machine can raise an OpCon Continuum event without an inbound network path to the platform. It writes a file of OpCon event syntax into the agent's MSGIN directory; the agent picks the file up, sends each line to Continuum over the connection it already holds open through its relay, and Continuum applies it.

Each line carries its own credential pair, which Continuum verifies and then checks against that service account's roles — so the machine needs a credential for this channel, but nothing on it holds an interactive Continuum sign-in.

The agent side of this already ships in every installed Windows and UNIX/Linux LSAM. Nothing on the machine has to change, and existing event files carry over unmodified.

This applies only to legacy agents reached through a relay. Universal agents have no MSGIN directory, and the setting described below is not offered for them.

Before any event can be applied: Default event environment​

Every event raised this way is applied to one environment, named on the agent's own registration.

WhereAgents → Legacy Agents & Groups, on the register or edit dialog for a legacy agent
FieldDefault event environment — an optional list of the tenant's environments
UnsetEvery event that machine raises is refused. There is no fallback to "the only environment" or "the first environment"
Clearing itClears the setting back to unset, which stops every event that machine raises
Set this before you rely on the channel

An unset Default event environment refuses events uniformly — not just the ones that address a schedule or a job. The machine has already deleted the event file by the time Continuum sees the line, so a refused event cannot be recovered by retrying: the process has to raise it again.

One machine resolves to one environment, and there is no per-event override. A machine that is shared across environments still sends everything to its configured default. The environment cannot be carried in the event text instead, because an event line names a schedule, not an environment, and the same schedule name legitimately exists in more than one environment.

The environment is read from the agent's registration on the platform side, so it cannot be overridden by anything the machine sends.

What a line has to look like​

Continuum treats an inbound line as an event when it starts with $ or #, followed by a name, a colon, a second name, and then a comma — for example:

$JOB:ADD,CURRENT,DAILY,MYJOB,Mon-Fri,opconuser,mytoken
$PROPERTY:ADD,DISK_PCT_PROD01,84,opconuser,mytoken

Anything else on the connection is handled as it always was, so this cannot disturb job status or machine up/down reporting.

The trailing credential pair is mandatory, and it is now verified​

Every line must end with two extra comma-separated values: a login ID and a token. This matches the legacy format, so files written for a legacy server work unchanged — and it is why a hand-authored line that omits them is refused.

The pair is checked. Earlier builds parsed it, masked it and recorded it, and then did not verify it — any machine that could write to its own MSGIN directory could raise any admitted event with no valid credential at all. Continuum now presents the pair to the Continuous identity system and rejects the line if it does not check out.

What a working credential is:

The tokenA service-account secret issued by the Continuous identity system for this tenant. A Classic external token is not one, so it has to be replaced
The login IDMust be the name of the service account that secret belongs to, compared ignoring case. The account name is what is verified against, so the login IDs already in your event files can stay as they are — you create service accounts named to match
What is recordedThe verified account name, against the event. The token is never persisted and appears in no record you can read
  • The field count is strict and includes the pair. A line with the wrong number of values is refused rather than partly applied — including a line that ends in a stray comma, which the refusal names specifically, because a trailing separator written by the emitting script is the usual cause.
Migrating an existing emitter changes the token, and nothing else

The MSGIN file format, the emitting scripts and the login ID all stay as they are. What changes is the token value in the emitter's configuration: create a service account whose name matches the login ID the file already carries, and put its secret where the old token was. Every Classic login ID carries over verbatim.

Grant that account only the roles it needs. The shipped Classic examples used an administrator login, and copying one is how a full-admin token ends up sitting in a shell script on every machine. A new credential has to be chosen anyway, so this is the moment to narrow it.

Create the account in the Continuous identity system. The Roles list carries an Event Identities action that looks like the place for it, but managing identities from Continuum is switched off and that section will tell you so.

The account's roles decide what the line may do

A line whose credential verifies is then checked against that service account's roles, the way a person's request would be. The account needs the permission the event requires, in the workspace of the object the event names and in the machine's Default event environment — for example, a $JOB:KILL line needs permission to delete job instances there. A line carrying property tokens also needs permission to view every global property it reads. A line the account may not perform is refused with EVENT_NOT_PERMITTED before it becomes an event, so it does not appear in the event log. The events refused for everyone stay refused whatever the account holds.

So grant each emitter's service account only what its event files need.

Verification is always on
  • There is no unverified mode. Every line is verified. A tenant the platform has no identity configuration for cannot have any line verified, so every line from that tenant is refused and lost — none is applied, and nothing reaches the event log.
  • The literal pair SYSTEM/MESSAGE is admitted without verification, for compatibility with a shipped legacy emitter. Lines that use it carry no account, so they are not checked against any roles either.

The SYSTEM/MESSAGE compatibility pair​

One shipped Windows legacy emitter writes the literal pair SYSTEM,MESSAGE with no customer configuration at all, and MESSAGE is not a service-account secret. So that exact pair — both halves, matched ignoring case — is admitted without being verified, or agent notification dispatch from that emitter would stop working on upgrade.

It is deliberately narrow:

  • Only these eight event types are admitted with it: $CONSOLE:DISPLAY, $NOTIFY:EMAIL, $NOTIFY:LOG, $NOTIFY:NETSEND, $NOTIFY:SNMP, $NOTIFY:SPOAL, $NOTIFY:TASKS and $NOTIFY:TEXTMSG. Any other event type presented with this pair is rejected.
  • $NOTIFY:COMMAND and $NOTIFY:SPOCO are excluded specifically, because both run something.
  • The match is on the pair, so a real service account that happens to be named SYSTEM neither gains this treatment nor is shadowed by it. The two are kept apart in the record: an event admitted this way is recorded as having used the compatibility pair and carries no verified identity.
An unverified path exists for those eight event types, and one of them now sends mail

There is no setting that turns this off, and it applies to every tenant. $NOTIFY:EMAIL is in the eight and takes a caller-supplied recipient, so anything that can write to a machine's MSGIN directory can send mail to any address, from your tenant, without presenting a credential of its own. Until $NOTIFY:EMAIL was implemented such a line was recorded and then failed; now it is delivered.

$NOTIFY:TEXTMSG and $NOTIFY:TASKS also take a caller-supplied recipient, but both are now refused outright, so neither sends anything.

Treat write access to MSGIN as sensitive on any machine you have not migrated, and restrict the directory accordingly.

A comma inside a value cannot be escaped

The format is positional and comma-separated with no escape character, so an entity name containing a comma shifts every value after it. The field-count rule catches the cases where the total no longer adds up, but a comma inside an earlier value can still produce a line that counts correctly and means something else. Avoid commas in any name an event file refers to.

Which events are applied​

Every event family in the catalog is admitted, which matches how the channel is used today: any job on the machine can write to MSGIN, so the platform does not try to guess which families a given site needs. Two narrowings and one gap are worth knowing:

RuleEffect
$MACHINE:STATUS and $MACHINE:MAXJOBS may name only the originating machineA line naming the machine itself is accepted (and then fails — see below); a line naming another machine is refused
$MACHINE:* wildcards (*, ?) are refusedA single line cannot address the whole estate
$MACHINE:* is admitted and then failsContinuum does not apply $MACHINE:STATUS or $MACHINE:MAXJOBS, so either is accepted at the edge and recorded as FAILED. Nothing is taken out of service
Eight $NOTIFY:* types are admitted and then refused$NOTIFY:COMMAND, $NOTIFY:LOG, $NOTIFY:NETSEND, $NOTIFY:SNMP, $NOTIFY:SPOAL, $NOTIFY:SPOCO, $NOTIFY:TASKS and $NOTIFY:TEXTMSG each depended on the OpCon server's own host, or are out of scope, and will not arrive later. The line is recorded FAILED with a message saying to remove or replace it — see why an event type failed

$NOTIFY:EMAIL from a machine now sends mail. It is the one $NOTIFY type the platform carries out, and a line that names it is applied like any other: the addresses, subject and body come off the line, and the message goes out through the same Email channel a notification group uses. A non-empty attachments field fails the line — there is no filesystem here to read attachment paths from. See Sending mail with $NOTIFY:EMAIL.

note

$MACHINE:* failing is deliberate rather than a defect. A green row for one of them would say a machine had been taken out of service when it had not — the same rule the event log applies to every event type the platform cannot act on.

$PROPERTY:ADD, $PROPERTY:SET and $PROPERTY:DELETE reach global, OI. and instance-scoped properties. A machine-scoped (MI.) name is still refused with a message naming the scope, so a script reporting a per-machine measurement under a machine-scoped name does not work. What does work now is writing a property onto a run — SI. for a workflow instance, JI. for a job instance.

From a machine, name the workflow and its schedule date in full: SI.DISK_PCT.20260930.NIGHTLY, or JI.DISK_PCT.20260930.NIGHTLY.EXTRACT. The shorthand that leaves those parts blank defaults them from the job or workflow that raised the event, and a line written into MSGIN was not raised by either, so a blank part is refused with Cannot default schedule name: event has no triggering instance. See Writing a property onto a running instance.

Property tokens in an event line​

A line may carry [[…]] property tokens, and they are resolved as the event is carried out — so a script can write $SCHEDULE:BUILD,[[OI.REGION]]_DAILY,[[$DATE]],… instead of computing the schedule name and the date in shell. Earlier builds passed the tokens through as literal text, which was refused or applied as the characters themselves.

What a line can reach is global properties and the clock ([[$DATE]], [[$TIME]], [[$NOW]]). A job-, schedule- or machine-scoped token has nothing to resolve against here and fails the event, as does a name no global property has — the message names the token as the file wrote it. [[…]] resolution is strict for exactly the reason the event log is worth reading: a mistyped name that rendered as its own text would look like a valid value and be applied.

The event type itself must be literal — a token in the first field is refused.

For the full rules, including what happens to an encrypted property and to a value that would carry a comma into the next field, see An event raised from outside a job.

How an agent-raised event is attributed​

In the event log, an event raised this way shows:

  • Source AGENT, and an AGENT actor naming the machine that raised it. The machine stays the actor even now that the credential is verified, because that is the field operators filter on.
  • The service account the credential belongs to — the name the identity system returned, not the name the line claimed. The two agree apart from case, and the record keeps whichever the account actually has.
  • The event line as received, with the credential pair stripped and the token masked.

The identity field tells you which of two things happened:

What the record showsWhat it means
A verified service account nameThe credential was exchanged and checked out, and the account was permitted the event
The compatibility pairThe line used SYSTEM/MESSAGE and carries no identity at all

That is more than the legacy behaviour offered: the file name, line number, emitting process and machine-side timestamp are not on the wire and so are not recorded. The machine name is, and it is the attribution to trace from.

Where a rejected event goes​

This matters more than it usually would, because the machine deletes the event file before Continuum has acknowledged anything. There is no error file written back to the machine — there is no channel for one — so the platform's own record is the only trace.

Rejections split into two groups, and only one of them is visible to you:

RejectedWhere you see it
At the platform edge — unknown event type, wrong field count, surplus values, an unset Default event environment, a $MACHINE line naming another machine or using a wildcard, a credential that fails verification, a service account without the permission the event needs, a tenant with no identity configuration, a line over 4,096 bytes (which takes its whole batch with it — see Delivery), or an event type the compatibility pair does not coverNot in the event log. The line never became an event. It is recorded in the platform's operational logs with the machine name, the event type and the reason
After the event was accepted — no handler for the type, a refused scope, a downstream failureIn the event log, as a FAILED event with the AGENT source, the machine name, and the error on its detail view
An edge rejection is invisible in the interface

If a machine's event file is not producing anything and nothing appears in the event log for it, that is consistent with the line being refused at the edge — most often an unset Default event environment or a field count that does not match. Confirm the setting first, then contact support with the machine name and the event type.

Delivery: at most once, and lossy​

The channel is not a queue, and this is the legacy behaviour rather than a Continuum choice — the installed agents delete the file before the platform acknowledges anything.

  • An event can be lost. A send failure loses the line, and on UNIX/Linux it loses the rest of the file with it, so partial application of a multi-line file is a reachable outcome.
  • The relay forwards lines in batches of up to 100, which can come from any of the machines behind it. A batch the relay cannot deliver is dropped whole, and so is a batch the platform refuses whole — which is what happens when any one line in it is over 4,096 bytes. One oversized line can therefore lose up to 99 other events, from other machines as well as its own. Keep every line under 4,096 bytes.
  • A line sent twice is applied twice. The relay gives each line its own identity when the line arrives from the agent, so the relay's own retries of a batch are recognised and applied once — but if the agent sends the same line again, it arrives as a new event. Two files with identical contents are likewise two separate events, which is correct — a script reporting the same measurement on a schedule is meant to record each one.
  • Ordering must not be relied on, either across files or between lines of one file. If one event has to be applied before another, put them in separate files and wait for the first to appear.
Good to know

For anything where the outcome matters, treat an event file as a request that usually arrives, and confirm the result rather than assuming it. The event log, filtered to source AGENT, is where to confirm.

Platform differences on the machine side​

These come from the installed agents and cannot be corrected by the platform, so they are worth knowing when an event file works on one machine and not another.

UNIX/LinuxWindows
A line with no leading $The agent adds one, so the line still worksSent as-is, and refused as an unknown event type
Very small filesA file of 16 bytes or fewer is ignored and never deleted, so it accumulates in the directoryHandled normally
A file still being writtenWaits for the file to stop changingCan read a partly-written file, producing a truncated line that is then refused
Non-ASCII textPassed through byte for byteDepends on the machine's own code page, and a UTF-8 byte-order mark corrupts the first line
Pickup delayUp to the agent's polling interval — 5 seconds by defaultUnder a second
caution
Write event files in plain ASCII, with a leading $

Both make a file behave the same way on either platform. On Windows, save without a byte-order mark.

Secrets in an agent-raised event​

$JOB:ADD, $JOB:ADDHLD, $SCHEDULE:BUILD and $SCHEDULE:BUILDHLD carry a properties field as Name=Value;Name2=Value2, and event files are written by hand — so a password can end up in one.

When one of these is raised by an agent and its properties field holds a value, that field and the values after it are replaced with a placeholder before the event is stored. The event is still applied with what the script sent; only the stored record is redacted. Two consequences:

  • The stored record shows a placeholder rather than the properties you sent, and the verbatim line is not kept for that event. The parsed fields are all still there.
  • Retry is refused for such an event, and the message says so: the original value cannot be recovered, so it has to be raised again from the machine that produced it.

An event that authors no properties value is unaffected and keeps its full record.

A $JOB:ADD from an agent never names an instance after a property value. A $JOB:ADD or $JOB:ADDHLD for a multi-instance job that carries properties and finds no Default instance adds an ad-hoc instance, and everywhere else that instance is named from the first property's value. Raised by an agent it is named AdHoc instead — numbered AdHoc$0001, AdHoc$0002… if that name is already in use. A job's name is shown in every listing and log entry of the job and is returned in the event's own state changes and messages, none of which the redaction above covers, so a value promoted into it would be readable in all of them. The property values themselves are still set on the instance, exactly as the line sent them.

Troubleshooting​

SymptomLikely causeWhat to do
Nothing happens, and no event appears in the logNo Default event environment on the agent, or the line's field count is wrongSet the environment on the agent's registration. Check the line ends with the login ID and token values and has no trailing comma
Events from a machine stopped working after an upgrade, and nothing appears in the logThe credential is now verified and the line's token is not a service-account secret — or the login ID doesn't match the account the secret belongs toCreate a service account named for the login ID already in the file and replace the token with its secret. See the credential pair
$JOB:* or $SCHEDULE:* lines from a machine are refused while its $NOTIFY:* lines are appliedThe emitter is using the SYSTEM/MESSAGE compatibility pair, which covers only eight event typesGive that emitter a real service-account credential
A line with a correct credential is refused, and nothing appears in the logThe credential verified, but the service account's roles don't grant the permission that event needs in the workspace it names and the machine's Default event environmentGrant the account a role with that permission, scoped to that workspace and environment
An event is refused shortly after a role change in the identity systemThe service account's role was withdrawn, so the credential no longer resolves or no longer carries the permissionRestore the role, or grant the account one that exists and is active
Several machines' events went missing at the same moment, and none appears in the logOne line in the relay's batch was over 4,096 bytes, so the whole batch was refusedFind and shorten the long line, then raise the lost events again
Every line from the tenant is refused, whatever the credentialThe platform has no identity configuration for the tenant, so no line can be verifiedContact support
The event appears as FAILED with not yet implementedA $MACHINE:STATUS or $MACHINE:MAXJOBS lineThese types are not applied. Use a workflow event or a notification group instead
The event appears as FAILED saying the type is not supported on this platformOne of the eight refused $NOTIFY typesIt will not arrive later. For mail, use $NOTIFY:EMAIL, which does work
A $NOTIFY:EMAIL line fails naming attachmentsEither the field really holds a path, or a comma in the message text shifted the text into itClear the field. The line format has no escape for a comma, so keep commas out of the message
The event appears as FAILED naming a property scopeA machine-scoped (MI.) property nameGlobal, OI. and instance-scoped (SI./JI./SSI./SJI.) names work; machine-scoped does not
The event appears as FAILED naming a [[…]] tokenThe line carries a property token that does not resolve, or one scoped to a job, schedule or machineCheck the global property's name. A line raised this way can reach globals and the clock only — see Property tokens in an event line
The event applied to the wrong environmentThe machine's Default event environment is not the one you expectedIt is per machine, not per event. Change the setting, or raise the event from a machine registered to the right environment
A $MACHINE:STATUS line for another machine is refusedOnly the originating machine may be addressedRaise it from that machine
Files pile up in the directory on a UNIX/Linux machineEach is 16 bytes or fewer, so the agent ignores themPad the line, or combine the content into a larger file
The first line of a file is refused on WindowsA byte-order mark, or a line with no leading $Save as ASCII without a byte-order mark, and start every line with $

Contact support when​

  • A well-formed line with the environment set produces neither an applied event nor a FAILED row in the event log.
  • An event applies but its recorded changes do not match what happened.

Include the machine name, the event type, the approximate time, and — if there is one — the event id and correlation id from the event log.