Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: moving spec table discussion out of table

...

Date-time that processing activities being logged begins. The value should be represented in UTC and formatted per ISO 8601, such as “2015-06-03T13:21:58+00:00”. The time should be shown with the maximum resolution available to the logging component (e.g., milliseconds, microseconds) by including the appropriate number of decimal digits. For example, when millisecond precision is available, the date-time value would be presented as, as “2015-06-03T13:21:58.340+00:00”.

Context dependent on whether part of an ENTRY marker

Audit requires this field

MDCGroupDescription

Applicable

(per log file)

Marker Associations

Required?

Y/N/C

(C= context dependent)

N = not required


Use Cases

Code References

RequestID


UUID to track the processing of each client request across all the ONAP components involved in its processing



Y

InvocationID

UUID correlates log entries relating to a single invocation of a single component



Y

InstanceUUID

UUID to differentiate between multiple instances of the same (named) log writing service/application



Y

ServiceName

The service inside the partner doing the call - includes API name



Y

PartnerName

The URI that the caller used to make the call to the component that is logging the message.



Y

StatusCode

This field indicates the high level status of the request - one of (COMPLETE, ERROR)




Y

ResponseCode
This field contains application-specific error codes.

Y



ResponseDescription
This field contains a human readable description of the ResponseCode.

Y



Severity

OPS specific

Use/Map existing? https://www.slf4j.org/api/org/apache/commons/logging/Log.html

ENUM is Logging level by default aligned with the reported log level - one of INFO/TRACE/DEBUG/WARN/ERROR/FATAL

By default - align this severity with the reported log level

(optionally a way to map actual level from reported level if required)



Y

ServerFQDN

This field contains the Virtual Machine (VM) Fully Qualified Domain Name (FQDN) The VM FQDN if the server is virtualized. Otherwise , it contains the the host name of the logging component.

Best effort (ip, fqdn)

(previously covered by removed "Server" field)

redundancy between clientIP, server, virtualServer name is OK - and helpfull for runtime OPS/Hybrid envs

superceedes virtualServerName

Report what is in the http header

Discussion: roll all 3 fqdn, hostname or ip into one field - do we ever need two of the 3 fields concurrently?

TODO: Verify what is also available from a filebeat agent when it exists

Y

ClientIPAddress

This field contains the requesting remote client application’s IP address if known. Otherwise this field can be empty.

We don't differentiate between inside/outside ONAP for the IP - this supports hybrid environments

Derived from the system

redundancy between clientIP, server, virtualServer name is OK - and helpfull for runtime OPS/Hybrid envs

Discussion: do we need both ip and fqdn fields?

Report what is in the http header

Y

EntryTimestamp

(previously BeginTimestamp)

C

InvokeTimestamp

(prevously

EndTimestamp)

Timestamp on invocation start

Context dependent on whether part of an INVOKE marker

metrics needs invoke

CTargetEntity

It contains the name of the ONAP component or sub-component, or external entity, at which the operation activities captured in this metrics log record is invoked.

Example: SDC-BE

CTargetServiceName

It contains the name  of the API or operation activities invoked (name on the remote/target application) at the TargetEntity.  

Example: Class name of rest endpoint

Discussion: on building call graph vs human readable single line - keep for human readable

Used as valuable URI - to annnote invoke marker

Review in terms of Marker-INVOKE - possiblly add INVOKE-return - to filter reporting

TBD: Coverage by log file type (debug, trace, ...)

TBD: cover off discussion on reducing log files to two (DEBUG/rest) for C* release

CTargetElement

VNF/PNF context dependent - on CRUD operations of VNF/PNFs

The IDs that need to be covered with the above Attributes are

       -        VNF_ID OR VNFC_ID : (Unique identifier for a VNF asset that is being instantiated or that would generate an alarms)

       -        VSERVER_ID OR VM_ID (or vmid): (Unique identified for a virtual server or virtual machine on which a Control Loop action is usually taken on, or that is installed  as part of instantiation flow)

       -        PNF : (What is the Unique identifier used within ONAP)

C

Logging

Via SLF4J:

Code Block
languagejava
linenumberstrue
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
// ...
final Logger logger = LoggerFactory.getLogger(this.getClass());
MDC.put("SomeUUID", UUID.randomUUID().toString());
try {
    logger.info("This message will have a UUID-valued 'SomeUUID' MDC attached.");
    // ...
}
finally {
    MDC.clear();
}



Y



ClientIPAddress

This field contains the requesting remote client application’s IP address if known. Otherwise empty.



Y



EntryTimestamp


UTC Date-time that processing activities being logged begins - if part of an ENTRY marker



C

InvokeTimestamp


Timestamp on invocation start - if part of an INVOKE marker



C

TargetEntity

It contains the name of the ONAP component or sub-component, or external entity, at which the operation activities captured in this metrics log record is invoked.

Example: SDC-BE



C

TargetServiceName

It contains the name  of the API or operation activities invoked (name on the remote/target application) at the TargetEntity.  

Example: Class name of rest endpoint

Discussion: on building call graph vs human readable single line - keep for human readable

Used as valuable URI - to annnote invoke marker

Review in terms of Marker-INVOKE - possiblly add INVOKE-return - to filter reporting

TBD: Coverage by log file type (debug, trace, ...)

TBD: cover off discussion on reducing log files to two (DEBUG/rest) for C* release



C

TargetElement

VNF/PNF context dependent - on CRUD operations of VNF/PNFs

The IDs that need to be covered with the above Attributes are

       -        VNF_ID OR VNFC_ID : (Unique identifier for a VNF asset that is being instantiated or that would generate an alarms)

       -        VSERVER_ID OR VM_ID (or vmid): (Unique identified for a virtual server or virtual machine on which a Control Loop action is usually taken on, or that is installed  as part of instantiation flow)

       -        PNF : (What is the Unique identifier used within ONAP)



C

Logging

Via SLF4J:

Code Block
languagejava
linenumberstrue
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
// ...
final Logger logger = LoggerFactory.getLogger(this.getClass());
MDC.put("SomeUUID", UUID.randomUUID().toString());
try {
    logger.info("This message will have a UUID-valued 'SomeUUID' MDC attached.");
    // ...
}
finally {
    MDC.clear();
}

EELF doesn't directly support MDCs, but its default provider (where com.att.eelf.configuration.SLF4jWrapper is the configured EELF provider)normally logs via SLF4J, and SLF4J will receive any MDC that is set:

Code Block
languagejava
linenumberstrue
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import com.att.eelf.configuration.EELFLogger;
import com.att.eelf.configuration.EELFManager;
// ...
final EELFLogger logger = EELFManager.getInstance().getLogger(this.getClass());
MDC.put("SomeUUID", UUID.randomUUID().toString());
try {
    logger.info("This message will have a UUID-valued 'SomeUUID' MDC attached.");
    // ...
}
finally {
    MDC.clear();
}

Serializing

Output of MDCs must ensure that:

  • All reported MDCs are logged with both name AND value. Logging output should not treat any MDCs as special.
  • All MDC names and values are escaped.

Escaping in Logback configuration can be achieved with:

Code Block
languagetext
linenumberstrue
%replace(%replace(%mdc){'\t','\\\\t'}){'\n','\\\\n'}

MDC - RequestID

This is often referred to by other names, including "Transaction ID", and one of several (pre-standardization) REST header names including X-ECOMP-RequestID and X-ONAP-RequestID.

ONAP logging uses a universally unique "RequestID" value in log records to track the processing of each client request across all the ONAP components involved in its processing. RequestID be propagated across all interfaces, not just REST Interfaces.

This value:

  • Is logged as a RequestID MDC. 
  • Is propagated between components in REST calls as an X-TransactionID HTTP header.

Receiving the X-TransactionID will vary by component according to APIs and frameworks. In generalEELF doesn't directly support MDCs, but its default provider (where com.att.eelf.configuration.SLF4jWrapper is the configured EELF provider)normally logs via SLF4J, and SLF4J will receive any MDC that is set:

Code Block
languagejava
linenumberstrue
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import com.att.eelf.configuration.EELFLogger;
import com.att.eelf.configuration.EELFManagerjavax.ws.rs.core.HttpHeaders;
// ...
final EELFLoggerHttpHeaders loggerheaders = EELFManager.getInstance().getLogger(this.getClass());
MDC.put("SomeUUID", UUID.randomUUID().toString());
try {
    logger.info("This message will have a UUID-valued 'SomeUUID' MDC attached.// ...
String txId = headers.getRequestHeaders().getFirst("X-TransactionID");
    // ...
}
finallyif (StringUtils.isBlank(txId)) {
	txId    MDC.clear= UUID.randomUUID().toString();
}

Serializing

Output of MDCs must ensure that:

  • All reported MDCs are logged with both name AND value. Logging output should not treat any MDCs as special.
  • All MDC names and values are escaped.

MDC.put("RequestID", txID);

Setting the X-TransactionID likewise will vary. For exampleEscaping in Logback configuration can be achieved with:

Code Block
languagetextjava
linenumberstrue
%replace(%replace(%mdc){'\t','\\\\t'}){'\n','\\\\n'}

MDC - RequestID

This is often referred to by other names, including "Transaction ID", and one of several (pre-standardization) REST header names including X-ECOMP-RequestID and X-ONAP-RequestID.

ONAP logging uses a universally unique "RequestID" value in log records to track the processing of each client request across all the ONAP components involved in its processing. RequestID be propagated across all interfaces, not just REST Interfaces.

This value:

  • Is logged as a RequestID MDC. 
  • Is propagated between components in REST calls as an X-TransactionID HTTP header.

Receiving the X-TransactionID will vary by component according to APIs and frameworks. In general:

Code Block
languagejava
linenumberstrue
import javax.ws.rs.core.HttpHeaders;
// ...
final HttpHeaders headers = ...;
// ...
String txId = headers.getRequestHeaders().getFirst("X-TransactionID");
if (StringUtils.isBlank(txId)) {
	txId = UUID.randomUUID().toString();
}
MDC.put("RequestID", txID);

Setting the X-TransactionID likewise will vary. For example:

Code Block
languagejava
linenumberstrue
final String txID = MDC.get("RequestID");
HttpURLConnection cx = ...;
// ...
cx.setRequestProperty("X-TransactionID", txID);

MDC - InvocationID

InvocationID is similar to RequestID, but where RequestID correlates records relating a single, top-level invocation of ONAP as it traverses many systems, InvocationID correlates log entries relating to a single invocation of a single component. Typically this means via REST, but in certain cases an InvocationID may be allocated without a new invocation, e.g. when a request is retried.

RequestID and InvocationID allow an execution graph to be derived. This requires that:

  • The relationship between RequestID and InvocationID is reported. 
  • The relationship between caller and recipient is reported for each invocation.

The proposed approach is that:

  • Callers:
    • Issue a new, unique InvocationID UUID for each downstream call they make. 
    • Log the new InvocationID, indicating the intent to invoke:
      • With Markers INVOKE, and SYNCHRONOUS if the invocation is synchronous.
      • With their own InvocationID still set as an MDC.
    • Pass the InvocationID as an X-InvocationID REST header.
  • Invoked components:
    • Retrieve the InvocationID from REST headers upon invocation, or generate a UUID default. 
    • Set the InvocationID MDC.
    • Write a log entry with the Marker ENTRY. (In EELF this will be to the AUDIT log).
    • Act as per Callers in all downstream requests. 
    • Write a log entry with the Marker EXIT upon return. (In EELF this will be to the METRIC log).
    • Unset all MDCs on exit.

That seems onerous, but:

...

final String txID = MDC.get("RequestID");
HttpURLConnection cx = ...;
// ...
cx.setRequestProperty("X-TransactionID", txID);

MDC - InvocationID

InvocationID is similar to RequestID, but where RequestID correlates records relating a single, top-level invocation of ONAP as it traverses many systems, InvocationID correlates log entries relating to a single invocation of a single component. Typically this means via REST, but in certain cases an InvocationID may be allocated without a new invocation, e.g. when a request is retried.

RequestID and InvocationID allow an execution graph to be derived. This requires that:

  • The relationship between RequestID and InvocationID is reported. 
  • The relationship between caller and recipient is reported for each invocation.

The proposed approach is that:

  • Callers:
    • Issue a new, unique InvocationID UUID for each downstream call they make. 
    • Log the new InvocationID, indicating the intent to invoke:
      • With Markers INVOKE, and SYNCHRONOUS if the invocation is synchronous.
      • With their own InvocationID still set as an MDC.
    • Pass the InvocationID as an X-InvocationID REST header.
  • Invoked components:
    • Retrieve the InvocationID from REST headers upon invocation, or generate a UUID default. 
    • Set the InvocationID MDC.
    • Write a log entry with the Marker ENTRY. (In EELF this will be to the AUDIT log).
    • Act as per Callers in all downstream requests. 
    • Write a log entry with the Marker EXIT upon return. (In EELF this will be to the METRIC log).
    • Unset all MDCs on exit.

That seems onerous, but:

  • It's only a few calls. 
  • It can be largely abstracted in the case of EELF logging.

MDC - InstanceUUID

If known, this field contains a universally unique identifier used to differentiate between multiple instances of the same (named) log writing service/application. Its value is set at instance creation time (and read by it, e.g., at start/initialization time from the environment). This value should be picked up by the component instance from its configuration file and subsequently used to enable differentiation of log records created by multiple, locally load balanced ONAP component or subcomponent instances that are otherwise identically configured.

Handles parallel threads or running across a load balanced set of microservices - for identification.

MDC - PartnerName

This field should contain the name of the client application user agent or user invoking the API. The identification of the entity that made the request being served. For a serving API that is authenticating the request, this should be the authenticated username or equivalent (e.g. a userid or a mechid). 

For example SDC-BE instead of just SDC for the overall pods

This is often used for heuristic analysis to identify invocations between ONAP individual ONAP components. Its value has never been clearly stipulated, so a common problem has been a lack of consistency. 

There is no clear consensus, but:

  • Use the short name of your component, e.g. xyzdriver. (try to incorporate both levels - the container name and the pod the container is in within the kubernetes deployment)
  • Values should be human-readable. 
  • Values should be fine-grained enough to disambiguate subcomponents where it's likely to matter. This is subjective. 
  • Be consistent: your component should ALWAYS report same value. 

Real-life examples include MSO, bpmnclient, BPELClient, (all of which are reported by SO), openECOMP (SDNC), vid (VID!) etc. (See the problem?)

Usage overlaps with InvocationID, which doesn't mean PartnerName gets retired, but which might mean it serves a more descriptive purpose. (Since it hasn't proven to be a great way of generating a call graph).

MDC - ServiceName

The URI that the caller used to make the call to the component that is logging the message.

For EELF Audit log records that capture API requests, this field contains the name of the API invoked at the component creating the record (e.g., Layer3ServiceActivateRequest).

For EELF Audit log records that capture processing as a result of receipt of a message, this field should contain the name of the module that processes the message.

Usage is the same for indexable logs. 

MDC - StatusCode

This field indicates the high level status of the request. It must have the value COMPLETE when the request is successful and ERROR when there is a failure.

Discussion: status/response/severity relationship

status = global, response below is app specific

Ability to render severity-like line in a non-debug log

MDC - ResponseCode

This field contains application-specific error codes. For consistency, common error categorizations should be used.

MDC - Severity

OPS specific

Use/Map existing https://www.slf4j.org/api/org/apache/commons/logging/Log.html

ENUM is INFO/TRACE/DEBUG/WARN/ERROR/FATAL

By default - align this severity with the reported log level

(optionally a way to map actual level from reported level if required)

MDC - ServerFQDN

This field contains the Virtual Machine (VM) Fully Qualified Domain Name (FQDN) if the server is virtualized. Otherwise, it contains the host name of the logging component.

Best effort (ip, fqdn)

(previously covered by removed "Server" field)

redundancy between clientIP, server, virtualServer name is OK - and helpfull for runtime OPS/Hybrid envs

superceedes virtualServerName

Report what is in the http header

Discussion: roll all 3 fqdn, hostname or ip into one field - do we ever need two of the 3 fields concurrently?

TODO: Verify what is also available from a filebeat agent when it exists

MDC - ClientIPAddress

(previously BeginTimestamp)

This field contains the requesting remote client application’s IP address if known. Otherwise this field can be empty.

We don't differentiate between inside/outside ONAP for the IP - this supports hybrid environments

Derived from the system

redundancy between clientIP, server, virtualServer name is OK - and helpfull for runtime OPS/Hybrid envs

Discussion: do we need both ip and fqdn fields?

Report what is in the http header

MDC - EntryTimestamp

Date-time that processing activities being logged begins. The value should be represented in UTC and formatted per ISO 8601, such as “2015-06-03T13:21:58+00:00”. The time should be shown with the maximum resolution available to the logging component (e.g., milliseconds, microseconds) by including the appropriate number of decimal digits. For example, when millisecond precision is available, the date-time value would be presented as, as “2015-06-03T13:21:58.340+00:00”.

Context dependent on whether part of an ENTRY marker

Audit requires this field

MDC - InvokeTimestamp

(prevously EndTimestamp)

Timestamp on invocation start.

Context dependent on whether part of an INVOKE marker

metrics needs this field

...

MDC - InstanceUUID

If known, this field contains a universally unique identifier used to differentiate between multiple instances of the same (named) log writing service/application. Its value is set at instance creation time (and read by it, e.g., at start/initialization time from the environment). This value should be picked up by the component instance from its configuration file and subsequently used to enable differentiation of log records created by multiple, locally load balanced ONAP component or subcomponent instances that are otherwise identically configured.

Handles parallel threads or running across a load balanced set of microservices - for identification.

MDC - PartnerName

This field should contain the name of the client application user agent or user invoking the API. The identification of the entity that made the request being served. For a serving API that is authenticating the request, this should be the authenticated username or equivalent (e.g. a userid or a mechid). 

For example SDC-BE instead of just SDC for the overall pods

This is often used for heuristic analysis to identify invocations between ONAP individual ONAP components. Its value has never been clearly stipulated, so a common problem has been a lack of consistency. 

There is no clear consensus, but:

  • Use the short name of your component, e.g. xyzdriver. (try to incorporate both levels - the container name and the pod the container is in within the kubernetes deployment)
  • Values should be human-readable. 
  • Values should be fine-grained enough to disambiguate subcomponents where it's likely to matter. This is subjective. 
  • Be consistent: your component should ALWAYS report same value. 

Real-life examples include MSO, bpmnclient, BPELClient, (all of which are reported by SO), openECOMP (SDNC), vid (VID!) etc. (See the problem?)

Usage overlaps with InvocationID, which doesn't mean PartnerName gets retired, but which might mean it serves a more descriptive purpose. (Since it hasn't proven to be a great way of generating a call graph).

MDC - ServiceName

The URI that the caller used to make the call to the component that is logging the message.

For EELF Audit log records that capture API requests, this field contains the name of the API invoked at the component creating the record (e.g., Layer3ServiceActivateRequest).

For EELF Audit log records that capture processing as a result of receipt of a message, this field should contain the name of the module that processes the message.

Usage is the same for indexable logs. 

MDC - StatusCode

This field indicates the high level status of the request. It must have the value COMPLETE when the request is successful and ERROR when there is a failure.

Discussion: status/response/severity relationship

status = global, response below is app specific

Ability to render severity-like line in a non-debug log

MDC - ResponseCode

This field contains application-specific error codes. For consistency, common error categorizations should be used.

MDCs - the Rest

Other MDCs are logged in a wide range of contexts.

...