Service Telemetry Events

Logs also use telemetry specification and request tracing/ tracking is accomplished by passing the request context into the logs and telemetry. This helps in troubleshooting issues. Request context has below details:

uid //user id from user authentication token in header (x-authenticated-user-token)
did //device id from request header (x-device-id)
sid //session id from request header (x-session-id)
reqId //request id from request header (x-request-id)

This request id also set to API response as msgid. This helps in tracking once request that invokes multiple APIs and flows.

Configuration

Telemetry has request context information and it is set during the telemetry logging.

Below are the properties set by the application to add the producer information into the telemetry data:

#Telemetry producer related info

telemetry_pdata_id=local.sunbird.learning.service
telemetry_pdata_pid=learning-service
telemetry_pdata_ver=5.1.0

Telemetry is logged and also send to SB-Obsrv data-pipeline using logback in groups service. logback.xml configuration has a kafka appender which will send the telemetry generated by the code to a kafka topic.

 <topic>${ENV_NAME}.telemetry.raw</topic>

Logback.xml configuration:

   <appender name="kafka-appender" class="com.github.danielwegener.logback.kafka.KafkaAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <pattern>%msg</pattern>
    </encoder>

    <topic>${ENV_NAME}.telemetry.raw</topic>
    <!-- ensure that every message sent by the executing host is partitioned to the same partition strategy -->
    <keyingStrategy class="com.github.danielwegener.logback.kafka.keying.NoKeyKeyingStrategy" />
    <!-- block the logging application thread if the kafka appender cannot keep up with sending the log messages -->
    <deliveryStrategy class="com.github.danielwegener.logback.kafka.delivery.AsynchronousDeliveryStrategy" />

    <!-- each <producerConfig> translates to regular kafka-client config (format: key=value) -->
    <!-- producer configs are documented here: https://kafka.apache.org/documentation.html#newproducerconfigs -->
    <!-- bootstrap.servers is the only mandatory producerConfig -->
    <producerConfig>bootstrap.servers=${SUNBIRD_KAFKA_URL}</producerConfig>
    <!-- don't wait for a broker to ack the reception of a batch.  -->
    <producerConfig>acks=0</producerConfig>
    <!-- wait up to 1000ms and collect log messages before sending them as a batch -->
    <producerConfig>linger.ms=15000</producerConfig>
    <!-- even if the producer buffer runs full, do not block the application but start to drop messages -->
    <producerConfig>max.block.ms=0</producerConfig>
    <!-- define a client-id that you use to identify yourself against the kafka broker -->
    <producerConfig>client.id=${HOSTNAME}-${CONTEXT_NAME}-logback-relaxed</producerConfig>

    <!-- there is no fallback <appender-ref>. If this appender cannot deliver, it will drop its messages. -->

  </appender>
  <!-- Telemetry Loggers-->
  <logger name="TelemetryEventLogger" level="INFO">
    <appender-ref ref="kafka-appender" />
  </logger>

List of Events

Audit Event
{
  "eid": "AUDIT",
  "ets": 1623221114913,
  "ver": "3.0",
  "mid": "b45c38b7ac160bea1524d72614150a18",
  "actor": {
    "id": "a10d5216-6b96-404c-8d1c-cc1f720d910a",
    "type": "User"
  },
  "context": {
    "channel": "01285019302823526477",
    "pdata": {
      "id": "dev.sunbird.groups.service",
      "pid": "groups-service",
      "ver": "4.0.0"
    },
    "env": "groups",
    "cdata": [
      {
        "id": "a10d5216-6b96-404c-8d1c-cc1f720d910a",
        "type": "User"
      },
      {
        "id": "7aa56a86-c088-4d88-bddb-7f766469d063",
        "type": "Groupid"
      },
      {
        "id": "b45c38b7ac160bea1524d72614150a18",
        "type": "Request"
      }
    ],
    "rollup": {
      "l1": "01285019302823526477"
    }
  },
  "edata": {
    "type": "update-group",
    "prevstate": "active",
    "pageid": "group-detail",
    "props": [
      "groupId",
      "name"
    ],
    "currentstate": "active"
  }
}
Error Event
{
  "eid": "ERROR",
  "ets": 1623224221640,
  "ver": "3.0",
  "mid": "ddc86837f8464603b260100966574a96",
  "actor": {
    "id": "a10d5216-6b96-404c-8d1c-cc1f720d910a",
    "type": "User"
  },
  "context": {
    "channel": "01285019302823526477",
    "pdata": {
      "id": "dev.sunbird.groups.service",
      "pid": "groups-service",
      "ver": "4.0.0"
    },
    "env": "groups",
    "cdata": [
      {
        "id": "ddc86837f8464603b260100966574a96",
        "type": "Request"
      }
    ],
    "rollup": {
      "l1": "01285019302823526477"
    }
  },
  "edata": {
    "errtype": "GROUP_NOT_FOUND",
    "stackTrace": "org.sunbird.service.GroupServiceImpl.readGroup(GroupServiceImpl.java:76)org.sunbird.actors.UpdateGro",
    "error": "group does not exist with this group Id 7aa56a86-sc088-4d88-bddb-7f766469d063."
  }
}
Log Event
{
  "eid": "LOG",
  "ets": 1623220836126,
  "ver": "3.0",
  "mid": "8b0cd46b9bf618dc04fa7cc38ecf97a1",
  "actor": {
    "id": "a10d5216-6b96-404c-8d1c-cc1f720d910a",
    "type": "User"
  },
  "context": {
    "channel": "01285019302823526477",
    "pdata": {
      "id": "dev.sunbird.groups.service",
      "pid": "groups-service",
      "ver": "4.0.0"
    },
    "env": "groups",
    "cdata": [
      {
        "id": "8b0cd46b9bf618dc04fa7cc38ecf97a1",
        "type": "Request"
      }
    ],
    "rollup": {
      "l1": "01285019302823526477"
    }
  },
  "edata": {
    "level": "info",
    "type": "Api_access",
    "message": "",
    "params": [
      {
        "url": "/v1/group/create"
      },
      {
        "method": "createGroup"
      },
      {
        "status": 200
      },
      {
        "duration": 0
      }
    ]
  }
}

Last updated