Configure facility id via a new attribute `saLogStreamFacilityId`.
The default value is 16 to keep the streaming feature backward compatible.

Adding 05 new test case into a new testsuite 22:
- Test configuring `saLogStreamFacilityId`.
- Verify if PRI field in package RFC5424 equals to
(saLogStreamFacilityId * 8 + severity).

Update README file.
---
 .../test_saImmOiRtObjectCreate_2.c            |   9 +-
 .../implementer/test_saImmOiRtObjectDelete.c  |   4 +-
 .../test_saImmOiRtObjectUpdate_2.c            |   4 +-
 src/log/Makefile.am                           |   9 +-
 src/log/README                                |  19 +-
 src/log/apitest/log_server.cc                 |  47 +++
 src/log/apitest/log_server.h                  |  35 +++
 .../apitest/tet_saLogStreamConfigFacilityId.c | 279 ++++++++++++++++++
 src/log/config/logsv_classes.xml              |  14 +
 src/log/logd/lgs_cache.cc                     |   1 +
 src/log/logd/lgs_dest.cc                      |   1 +
 src/log/logd/lgs_dest.h                       |   6 +-
 src/log/logd/lgs_imm.cc                       |  74 ++++-
 src/log/logd/lgs_mbcsv.cc                     | 187 +++++++++++-
 src/log/logd/lgs_mbcsv.h                      |   5 +-
 src/log/logd/lgs_mbcsv_v9.cc                  | 243 +++++++++++++++
 src/log/logd/lgs_mbcsv_v9.h                   |  67 +++++
 src/log/logd/lgs_recov.cc                     |  10 +
 src/log/logd/lgs_stream.cc                    |   9 +
 src/log/logd/lgs_stream.h                     |   1 +
 src/log/logd/lgs_unixsock_dest.cc             |   7 +-
 src/log/tests/lgs_dest_test.cc                |   3 +
 22 files changed, 1009 insertions(+), 25 deletions(-)
 create mode 100644 src/log/apitest/log_server.cc
 create mode 100644 src/log/apitest/log_server.h
 create mode 100644 src/log/apitest/tet_saLogStreamConfigFacilityId.c
 create mode 100644 src/log/logd/lgs_mbcsv_v9.cc
 create mode 100644 src/log/logd/lgs_mbcsv_v9.h

diff --git a/src/imm/apitest/implementer/test_saImmOiRtObjectCreate_2.c 
b/src/imm/apitest/implementer/test_saImmOiRtObjectCreate_2.c
index df260a9d5..709332954 100644
--- a/src/imm/apitest/implementer/test_saImmOiRtObjectCreate_2.c
+++ b/src/imm/apitest/implementer/test_saImmOiRtObjectCreate_2.c
@@ -59,9 +59,11 @@ static SaImmAttrValuesT_2 v10 = {"saLogStreamSeverityFilter",
                                 SA_IMM_ATTR_SAUINT32T, 1, (void **)int1Values};
 static SaImmAttrValuesT_2 v11 = {"saLogStreamCreationTimestamp",
                                 SA_IMM_ATTR_SATIMET, 1, (void **)lint1Values};
+static SaImmAttrValuesT_2 v12 = {"saLogStreamFacilityId",
+                               SA_IMM_ATTR_SAUINT32T, 1, (void **)int1Values};
 
 static const SaImmAttrValuesT_2 *attrValues[] = {
-    &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, NULL};
+    &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, &v12, NULL};
 static const SaImmClassNameT className = "SaLogStream";
 
 void saImmOiRtObjectCreate_2_01(void)
@@ -188,8 +190,9 @@ void saImmOiRtObjectCreate_2_07(void)
        // const SaNameT *nameValues27[] = {&rdnObj27};
        const SaImmAttrValuesT_2 v27 = {"safLgStr", SA_IMM_ATTR_SASTRINGT, 1,
                                        (void **)nameValues27};
-       const SaImmAttrValuesT_2 *attrValues27[] = {
-           &v1, &v27, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, NULL};
+       const SaImmAttrValuesT_2 *attrValues27[] = {&v1,  &v27, &v3, &v4, &v5,
+                                                   &v6,  &v7,  &v8, &v9, &v10,
+                                                   &v11, &v12, NULL};
 
        SaNameT tmpName;
 
diff --git a/src/imm/apitest/implementer/test_saImmOiRtObjectDelete.c 
b/src/imm/apitest/implementer/test_saImmOiRtObjectDelete.c
index 986ec88aa..341d5144a 100644
--- a/src/imm/apitest/implementer/test_saImmOiRtObjectDelete.c
+++ b/src/imm/apitest/implementer/test_saImmOiRtObjectDelete.c
@@ -59,9 +59,11 @@ static SaImmAttrValuesT_2 v10 = {"saLogStreamSeverityFilter",
                                 SA_IMM_ATTR_SAUINT32T, 1, (void **)int1Values};
 static SaImmAttrValuesT_2 v11 = {"saLogStreamCreationTimestamp",
                                 SA_IMM_ATTR_SATIMET, 1, (void **)lint1Values};
+static SaImmAttrValuesT_2 v12 = {"saLogStreamFacilityId",
+                               SA_IMM_ATTR_SAUINT32T, 1, (void **)int1Values};
 
 static const SaImmAttrValuesT_2 *attrValues[] = {
-    &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, NULL};
+    &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, &v12, NULL};
 static const SaImmClassNameT className = "SaLogStream";
 
 void saImmOiRtObjectDelete_01(void)
diff --git a/src/imm/apitest/implementer/test_saImmOiRtObjectUpdate_2.c 
b/src/imm/apitest/implementer/test_saImmOiRtObjectUpdate_2.c
index 1a551fd9f..2f2b941dc 100644
--- a/src/imm/apitest/implementer/test_saImmOiRtObjectUpdate_2.c
+++ b/src/imm/apitest/implementer/test_saImmOiRtObjectUpdate_2.c
@@ -55,9 +55,11 @@ static SaImmAttrValuesT_2 v10 = {"saLogStreamSeverityFilter",
                                 SA_IMM_ATTR_SAUINT32T, 1, (void **)int1Values};
 static SaImmAttrValuesT_2 v11 = {"saLogStreamCreationTimestamp",
                                 SA_IMM_ATTR_SATIMET, 1, (void **)lint1Values};
+static SaImmAttrValuesT_2 v12 = {"saLogStreamFacilityId",
+                               SA_IMM_ATTR_SAUINT32T, 1, (void **)int1Values};
 
 static const SaImmAttrValuesT_2 *attrValues[] = {
-    &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, NULL};
+    &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, &v12, NULL};
 
 static const SaImmClassNameT className = "SaLogStream";
 
diff --git a/src/log/Makefile.am b/src/log/Makefile.am
index 767e25369..2dad3cfb1 100644
--- a/src/log/Makefile.am
+++ b/src/log/Makefile.am
@@ -87,6 +87,7 @@ noinst_HEADERS += \
        src/log/logd/lgs_mbcsv_v3.h \
        src/log/logd/lgs_mbcsv_v5.h \
        src/log/logd/lgs_mbcsv_v6.h \
+       src/log/logd/lgs_mbcsv_v9.h \
        src/log/logd/lgs_oi_admin.h \
        src/log/logd/lgs_recov.h \
        src/log/logd/lgs_stream.h \
@@ -151,6 +152,7 @@ bin_osaflogd_SOURCES = \
        src/log/logd/lgs_mbcsv_v3.cc \
        src/log/logd/lgs_mbcsv_v5.cc \
        src/log/logd/lgs_mbcsv_v6.cc \
+       src/log/logd/lgs_mbcsv_v9.cc \
        src/log/logd/lgs_mds.cc \
        src/log/logd/lgs_oi_admin.cc \
        src/log/logd/lgs_recov.cc \
@@ -188,7 +190,8 @@ bin_PROGRAMS += bin/logtest bin/saflogtest bin/logtestfr
 noinst_HEADERS += \
        src/log/apitest/logtest.h \
        src/log/apitest/logutil.h \
-       src/log/apitest/imm_tstutil.h
+       src/log/apitest/imm_tstutil.h \
+       src/log/apitest/log_server.h
 
 bin_logtest_CFLAGS = $(AM_CFLAGS) -Wformat=1
 
@@ -225,7 +228,9 @@ bin_logtest_SOURCES = \
        src/log/apitest/tet_Log_clm.c \
        src/log/apitest/tet_cfg_destination.c \
        src/log/apitest/tet_multiple_thread.c \
-       src/log/apitest/tet_saLogWriteLogAsync_cache.c
+       src/log/apitest/tet_saLogWriteLogAsync_cache.c \
+       src/log/apitest/tet_saLogStreamConfigFacilityId.c \
+       src/log/apitest/log_server.cc
 
 bin_logtest_LDADD = \
        lib/libapitest.la \
diff --git a/src/log/README b/src/log/README
index 0d01e65d5..1d5469d6c 100644
--- a/src/log/README
+++ b/src/log/README
@@ -806,4 +806,21 @@ To test this feature, a GCC flag is added during compile 
time to simulate,
 SIMULATE_NFS_UNRESPONSE, the case the underlying file system is unresponsive,
 and it only takes effect when the cache size is given to a non-zero value. With
 that, the I/O thread will sleep *16 seconds* every 02 write requests. The flag
-is disabled in default.
\ No newline at end of file
+is disabled in default.
+
+
+5. Make facility ID configurable (#3131)
+----------------------------------------------
+Streaming log record is packaged in RFC5424 format and they all carry a fixed
+facility ID (16). Therefore, log record receiver i.e. rsyslogd is not able to
+filter log records on their facility id such as which ones are regular logs
+or which ones are security.
+
+The ticket to have the facility ID configurable so that the receiver can
+differentiate among types of log records based on that number.
+
+Configure facility id via a new attribute `saLogStreamFacilityId` in class
+`SaLogStreamConfig`. The valid range is [0-23]. The default value is 16 to keep
+the streaming feature backward compatible. Always keep the value of attribute
+`saLogStreamFacilityId` in sync with the standby. If user deletes value of the
+attribute `saLogStreamFacilityId`, it will go back to the default value (16).
diff --git a/src/log/apitest/log_server.cc b/src/log/apitest/log_server.cc
new file mode 100644
index 000000000..81bb3d651
--- /dev/null
+++ b/src/log/apitest/log_server.cc
@@ -0,0 +1,47 @@
+/*      -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2020 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "log/apitest/log_server.h"
+#include "base/unix_server_socket.h"
+
+static base::UnixServerSocket *server;
+
+void StartUnixServer() {
+  server = new base::UnixServerSocket("/tmp/test.sock",
+                                      base::UnixSocket::kNonblocking, 0777);
+  server->fd();
+}
+
+bool FindExpectedPRI(char *PRI_Field, char *msg) {
+  char *buf = new char[1024];
+  bool isFound = false;
+  do {
+    memset(buf, 0, 1024);
+    size_t len = server->Recv(buf, 1024);
+    buf[len] = '\0';
+    if (!strncmp(buf, PRI_Field, strlen(PRI_Field))) {
+      isFound = true;
+    }
+  } while (!strstr(buf, msg));
+  delete[] buf;
+  return isFound;
+}
+
+void StopUnixServer() {
+  server->~UnixServerSocket();
+  delete server;
+}
diff --git a/src/log/apitest/log_server.h b/src/log/apitest/log_server.h
new file mode 100644
index 000000000..752d42007
--- /dev/null
+++ b/src/log/apitest/log_server.h
@@ -0,0 +1,35 @@
+/*      -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2020 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef LOG_APITEST_LOG_SERVER_H_
+#define LOG_APITEST_LOG_SERVER_H_
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void StartUnixServer();
+bool FindExpectedPRI(char *data, char *msg);
+void StopUnixServer();
+
+#ifdef __cplusplus
+}  // closing brace for extern "C"
+#endif
+
+#endif  // LOG_APITEST_LOG_SERVER_H_
diff --git a/src/log/apitest/tet_saLogStreamConfigFacilityId.c 
b/src/log/apitest/tet_saLogStreamConfigFacilityId.c
new file mode 100644
index 000000000..f8d44c202
--- /dev/null
+++ b/src/log/apitest/tet_saLogStreamConfigFacilityId.c
@@ -0,0 +1,279 @@
+/*      -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2020 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "log/apitest/log_server.h"
+#include "log/apitest/logtest.h"
+
+typedef enum { ACTIVE_NODE = 0, STANDBY_NODE = 1, PAYLOAD = 2 } role;
+
+//>
+// 02 test cases about configuring `saLogStreamFacilityId`:
+// 1) try to set a valid value, expect getting OK.
+// 2) try to set an invalid value, expect getting NOK.
+//<
+
+// TC#1: Set a valid value to `saLogStreamFacilityId`
+void config_saLogStreamFacilityId_1()
+{
+       const char *command =
+           "immcfg -a saLogStreamFacilityId=4 " SA_LOG_STREAM_SYSTEM;
+       rc_validate(systemCall(command), EXIT_SUCCESS);
+
+       /* Restore the value back to the default value */
+       command = "immcfg -a saLogStreamFacilityId= " SA_LOG_STREAM_SYSTEM;
+       (void)systemCall(command);
+}
+
+// TC#2: Set an invalid value to `saLogStreamFacilityId`
+void config_saLogStreamFacilityId_2()
+{
+       const char *command =
+           "immcfg -a saLogStreamFacilityId=24 " SA_LOG_STREAM_SYSTEM
+           " 2> /dev/null";
+       rc_validate(systemCall(command), EXIT_FAILURE);
+}
+
+static void switch_over()
+{
+       const char *command =
+           "amf-adm si-swap safSi=SC-2N,safApp=OpenSAF 2>/dev/null";
+       (void)systemCall(command);
+}
+
+static uint8_t get_role()
+{
+       char node[256];
+       sprintf(node, "SC-%d", get_active_sc());
+       if (strncmp("PL", hostname(), 2) == 0) {
+               return PAYLOAD;
+       } else {
+               if (strcmp(node, hostname()) == 0)
+                       return ACTIVE_NODE;
+               return STANDBY_NODE;
+       }
+}
+
+static void setup(uint32_t facilityId)
+{
+       const char dest[] = "test;UNIX_SOCKET;/tmp/test.sock";
+       char command[1000];
+
+       StartUnixServer();
+
+       memset(command, 0, sizeof(command));
+       sprintf(
+           command,
+           "immcfg -a logRecordDestinationConfiguration=\"%s\" %s 2>/dev/null",
+           dest, SA_LOG_CONFIGURATION_OBJECT);
+       (void)systemCall(command);
+
+       sprintf(command, "immcfg -a saLogRecordDestination=test %s 2>/dev/null",
+               SA_LOG_STREAM_SYSTEM);
+       (void)systemCall(command);
+
+       memset(command, 0, sizeof(command));
+       if (facilityId < 24) {
+               sprintf(command,
+                       "immcfg -a saLogStreamFacilityId=%d %s 2>/dev/null",
+                       facilityId, SA_LOG_STREAM_SYSTEM);
+       } else {
+               sprintf(command,
+                       "immcfg -a saLogStreamFacilityId= %s 2>/dev/null",
+                       SA_LOG_STREAM_SYSTEM);
+       }
+       (void)systemCall(command);
+}
+
+static void restore_default_value()
+{
+       char command[1000];
+
+       /* Restore the value back to the default value */
+       memset(command, 0, sizeof(command));
+       sprintf(command, "immcfg -a saLogStreamFacilityId= %s 2>/dev/null",
+               SA_LOG_STREAM_SYSTEM);
+       (void)systemCall(command);
+
+       memset(command, 0, sizeof(command));
+       sprintf(command, "immcfg -a saLogRecordDestination= %s 2>/dev/null",
+               SA_LOG_STREAM_SYSTEM);
+       (void)systemCall(command);
+
+       memset(command, 0, sizeof(command));
+       sprintf(command,
+               "immcfg -a logRecordDestinationConfiguration= %s 2>/dev/null",
+               SA_LOG_CONFIGURATION_OBJECT);
+       (void)systemCall(command);
+}
+
+//>
+// TC#3: Verify if PRI = 38 (saLogStreamFacilityId * 8 + severity) in package
+// RFC5424 format.The test must run on active node.
+//
+// Change `saLogStreamFacilityId = 4` and send the log record with severity = 6
+//<
+void streaming_log_record_then_verify_PRI_1()
+{
+       if (get_role() != ACTIVE_NODE) {
+               test_validate(true, true);
+               return;
+       }
+
+       setup(4);
+
+       strcpy((char *)genLogRecord.logBuffer->logBuf, __FUNCTION__);
+       genLogRecord.logBuffer->logBufSize = strlen(__FUNCTION__);
+       genLogRecord.logHeader.genericHdr.logSeverity = SA_LOG_SEV_INFO;
+
+       rc = logInitialize();
+       if (rc != SA_AIS_OK) {
+               test_validate(rc, SA_AIS_OK);
+               goto done;
+       }
+
+       rc = logStreamOpen(&systemStreamName);
+       if (rc != SA_AIS_OK) {
+               test_validate(rc, SA_AIS_OK);
+               goto done;
+       }
+
+       rc = logWriteAsync(&genLogRecord);
+       if (rc != SA_AIS_OK) {
+               test_validate(rc, SA_AIS_OK);
+               goto done;
+       }
+
+       test_validate(FindExpectedPRI("<38>", (char *)__FUNCTION__), true);
+
+done:
+       restore_default_value();
+       logStreamClose();
+       logFinalize();
+       StopUnixServer();
+}
+
+//>
+// TC#4: Verify if PRI = 134 (saLogStreamFacilityId (16)* 8 + severity) in
+// package RFC5424 format.The test must run on active node.
+//
+// Delete attribute `saLogStreamFacilityId` and send the log record with
+// severity = 6(information message)
+//<
+void streaming_log_record_then_verify_PRI_2()
+{
+       if (get_role() != ACTIVE_NODE) {
+               test_validate(true, true);
+               return;
+       }
+
+       setup(127);
+
+       strcpy((char *)genLogRecord.logBuffer->logBuf, __FUNCTION__);
+       genLogRecord.logBuffer->logBufSize = strlen(__FUNCTION__);
+       genLogRecord.logHeader.genericHdr.logSeverity = SA_LOG_SEV_INFO;
+
+       rc = logInitialize();
+       if (rc != SA_AIS_OK) {
+               test_validate(rc, SA_AIS_OK);
+               goto done;
+       }
+
+       rc = logStreamOpen(&systemStreamName);
+       if (rc != SA_AIS_OK) {
+               test_validate(rc, SA_AIS_OK);
+               goto done;
+       }
+
+       rc = logWriteAsync(&genLogRecord);
+       if (rc != SA_AIS_OK) {
+               test_validate(rc, SA_AIS_OK);
+               goto done;
+       }
+
+       test_validate(FindExpectedPRI("<134>", (char *)__FUNCTION__), true);
+
+done:
+       restore_default_value();
+       logStreamClose();
+       logFinalize();
+       StopUnixServer();
+}
+
+//>
+// TC#5: This test case verify if the PRI=38 after trigger switch-over and
+// streaming log record ('PRI'field in package RFC5425 ).The test must run
+// on standby node.
+//<
+void streaming_log_record_then_verify_PRI_3()
+{
+       if (get_role() != STANDBY_NODE) {
+               test_validate(true, true);
+               return;
+       }
+
+       setup(4);
+
+       switch_over();
+
+       strcpy((char *)genLogRecord.logBuffer->logBuf, __FUNCTION__);
+       genLogRecord.logBuffer->logBufSize = strlen(__FUNCTION__);
+       genLogRecord.logHeader.genericHdr.logSeverity = SA_LOG_SEV_INFO;
+
+       rc = logInitialize();
+       if (rc != SA_AIS_OK) {
+               test_validate(rc, SA_AIS_OK);
+               goto done;
+       }
+
+       rc = logStreamOpen(&systemStreamName);
+       if (rc != SA_AIS_OK) {
+               test_validate(rc, SA_AIS_OK);
+               goto done;
+       }
+
+       rc = logWriteAsync(&genLogRecord);
+       if (rc != SA_AIS_OK) {
+               test_validate(rc, SA_AIS_OK);
+               goto done;
+       }
+
+       test_validate(FindExpectedPRI("<38>", (char *)__FUNCTION__), true);
+
+done:
+       restore_default_value();
+       logStreamClose();
+       logFinalize();
+       StopUnixServer();
+}
+
+__attribute__((constructor)) static void saLibraryLifeCycle_constructor(void)
+{
+       test_suite_add(22, "Test log stream config facility id");
+       test_case_add(22, config_saLogStreamFacilityId_1,
+                     "Set a valid value to saLogStreamFacilityId");
+       test_case_add(22, config_saLogStreamFacilityId_2,
+                     "Set a invalid value to saLogStreamFacilityId");
+       test_case_add(22, streaming_log_record_then_verify_PRI_1,
+                     "Streaming with configure saLogStreamFacilityId=4 and "
+                     "verify PRI field");
+       test_case_add(
+           22, streaming_log_record_then_verify_PRI_2,
+           "Delelte attribute saLogStreamFacilityId and verify PRI field");
+       test_case_add(22, streaming_log_record_then_verify_PRI_3,
+                     "Trigger switch-over then verify PRI field in package "
+                     "RFC5424 format");
+}
diff --git a/src/log/config/logsv_classes.xml b/src/log/config/logsv_classes.xml
index 084e8915d..8aa8e69c2 100644
--- a/src/log/config/logsv_classes.xml
+++ b/src/log/config/logsv_classes.xml
@@ -78,6 +78,12 @@
                        <type>SA_UINT64_T</type>
                        <category>SA_RUNTIME</category>
                </attr>
+               <attr>
+                       <name>saLogStreamFacilityId</name>
+                       <type>SA_UINT32_T</type>
+                       <category>SA_RUNTIME</category>
+                       <flag>SA_CACHED</flag>
+               </attr>
        </class>
        <class name="SaLogStreamConfig">
                <category>SA_CONFIG</category>
@@ -171,6 +177,14 @@
                        <type>SA_UINT64_T</type>
                        <category>SA_RUNTIME</category>
                </attr>
+               <attr>
+                       <name>saLogStreamFacilityId</name>
+                       <type>SA_UINT32_T</type>
+                       <category>SA_CONFIG</category>
+                       <flag>SA_WRITABLE</flag>
+                       <flag>SA_STRONG_DEFAULT</flag>
+                       <default-value>16</default-value>
+               </attr>
        </class>
        <class name="OpenSafLogConfig">
 <!-- Care is needed when changing to the default values for the attributes of 
this class
diff --git a/src/log/logd/lgs_cache.cc b/src/log/logd/lgs_cache.cc
index d94f4ea0d..81f64225d 100644
--- a/src/log/logd/lgs_cache.cc
+++ b/src/log/logd/lgs_cache.cc
@@ -161,6 +161,7 @@ void Cache::Data::Streaming() const {
   data.hostname    = param_->from_node;
   data.appname     = param_->svc_name;
   data.sev         = param_->severity;
+  data.facilityId  = stream->facilityId;
   time.tv_sec      = (param_->log_stamp / (SaTimeT)SA_TIME_ONE_SECOND);
   time.tv_nsec     = (param_->log_stamp % (SaTimeT)SA_TIME_ONE_SECOND);
   data.time        = time;
diff --git a/src/log/logd/lgs_dest.cc b/src/log/logd/lgs_dest.cc
index 0e70ddd12..71aecc92d 100644
--- a/src/log/logd/lgs_dest.cc
+++ b/src/log/logd/lgs_dest.cc
@@ -392,6 +392,7 @@ bool WriteToDestination(const RecordData& data, const 
VectorString& destnames) {
   info.stream_dn = data.name;
   info.app_name = data.appname;
   info.severity = data.sev;
+  info.facilityId = data.facilityId;
   info.time = data.time;
   info.origin = origin.c_str();
 
diff --git a/src/log/logd/lgs_dest.h b/src/log/logd/lgs_dest.h
index 6fe7c1782..c119de356 100644
--- a/src/log/logd/lgs_dest.h
+++ b/src/log/logd/lgs_dest.h
@@ -75,6 +75,7 @@ struct RecordData {
   bool isRtStream;
   uint32_t recordId;
   uint16_t sev;
+  uint32_t facilityId;
   timespec time;
 
   RecordData()
@@ -86,7 +87,8 @@ struct RecordData {
         msgid{nullptr},
         isRtStream{false},
         recordId{0},
-        sev{0} {
+        sev{0},
+        facilityId{16} {
     time = base::ReadRealtimeClock();
   }
 };
@@ -175,6 +177,7 @@ class DestinationHandler {
     const char* log_record;
     const char* app_name;
     uint16_t severity;
+    uint32_t facilityId;
     uint32_t record_id;
     struct timespec time;
 
@@ -186,6 +189,7 @@ class DestinationHandler {
           log_record{nullptr},
           app_name{nullptr},
           severity{0},
+          facilityId{16},
           record_id{0} {
       time = base::ReadRealtimeClock();
     }
diff --git a/src/log/logd/lgs_imm.cc b/src/log/logd/lgs_imm.cc
index 24318bf90..40551693d 100644
--- a/src/log/logd/lgs_imm.cc
+++ b/src/log/logd/lgs_imm.cc
@@ -56,6 +56,7 @@
 #include "log/logd/lgs_mbcsv_v3.h"
 #include "log/logd/lgs_mbcsv_v5.h"
 #include "log/logd/lgs_mbcsv_v6.h"
+#include "log/logd/lgs_mbcsv_v9.h"
 #include "base/saf_error.h"
 
 /* TYPE DEFINITIONS
@@ -245,12 +246,40 @@ static uint32_t ckpt_stream_config(log_stream_t *stream) {
   lgsv_ckpt_msg_v1_t ckpt_v1;
   lgsv_ckpt_msg_v2_t ckpt_v2;
   lgsv_ckpt_msg_v6_t ckpt_v3;
+  lgsv_ckpt_msg_v9_t ckpt_v4;
 
   void *ckpt_ptr;
 
   TRACE_ENTER();
 
-  if (lgs_is_peer_v6()) {
+  if (lgs_is_peer_v9()) {
+    memset(&ckpt_v4, 0, sizeof(ckpt_v4));
+    ckpt_v4.header.ckpt_rec_type = LGS_CKPT_CFG_STREAM;
+    ckpt_v4.header.num_ckpt_records = 1;
+    ckpt_v4.header.data_len = 1;
+
+    ckpt_v4.ckpt_rec.stream_cfg.name = const_cast<char 
*>(stream->name.c_str());
+    ckpt_v4.ckpt_rec.stream_cfg.fileName =
+        const_cast<char *>(stream->fileName.c_str());
+    ckpt_v4.ckpt_rec.stream_cfg.pathName =
+        const_cast<char *>(stream->pathName.c_str());
+    ckpt_v4.ckpt_rec.stream_cfg.maxLogFileSize = stream->maxLogFileSize;
+    ckpt_v4.ckpt_rec.stream_cfg.fixedLogRecordSize = 
stream->fixedLogRecordSize;
+    ckpt_v4.ckpt_rec.stream_cfg.logFullAction = stream->logFullAction;
+    ckpt_v4.ckpt_rec.stream_cfg.logFullHaltThreshold =
+        stream->logFullHaltThreshold;
+    ckpt_v4.ckpt_rec.stream_cfg.maxFilesRotated = stream->maxFilesRotated;
+    ckpt_v4.ckpt_rec.stream_cfg.logFileFormat = stream->logFileFormat;
+    ckpt_v4.ckpt_rec.stream_cfg.severityFilter = stream->severityFilter;
+    ckpt_v4.ckpt_rec.stream_cfg.logFileCurrent =
+        const_cast<char *>(stream->logFileCurrent.c_str());
+    ckpt_v4.ckpt_rec.stream_cfg.dest_names =
+        const_cast<char *>(stream->stb_dest_names.c_str());
+    ckpt_v4.ckpt_rec.stream_cfg.c_file_close_time_stamp =
+        stream->act_last_close_timestamp;
+    ckpt_v4.ckpt_rec.stream_cfg.facilityId = stream->facilityId;
+    ckpt_ptr = &ckpt_v4;
+  } else if (lgs_is_peer_v6()) {
     memset(&ckpt_v3, 0, sizeof(ckpt_v3));
     ckpt_v3.header.ckpt_rec_type = LGS_CKPT_CFG_STREAM;
     ckpt_v3.header.num_ckpt_records = 1;
@@ -1281,6 +1310,8 @@ static SaAisErrorT check_attr_validity(
   bool i_maxFilesRotated_mod = false;
   SaUint32T i_severityFilter = 0;
   bool i_severityFilter_mod = false;
+  SaUint32T i_facilityId = 0;
+  bool i_facilityId_mod = false;
 
   TRACE_ENTER();
 
@@ -1338,7 +1369,8 @@ static SaAisErrorT check_attr_validity(
     if (attribute->attrValuesNumber > 0) {
       value = attribute->attrValues[0];
     } else if (opdata->operationType == CCBUTIL_MODIFY) {
-      if (!strcmp(attribute->attrName, "saLogRecordDestination")) {
+      if (!strcmp(attribute->attrName, "saLogRecordDestination") ||
+          !strcmp(attribute->attrName, "saLogStreamFacilityId")) {
         // do nothing
       } else {
         /* An attribute without a value is never valid if modify */
@@ -1403,6 +1435,11 @@ static SaAisErrorT check_attr_validity(
       i_severityFilter_mod = true;
       TRACE("Saved attribute \"%s\" = %d", attribute->attrName,
             i_severityFilter);
+    } else if (!strcmp(attribute->attrName, "saLogStreamFacilityId") &&
+               attribute->attrValuesNumber > 0) {
+      i_facilityId = *(reinterpret_cast<SaUint32T *>(value));
+      i_facilityId_mod = true;
+      TRACE("Saved attribute \"%s\"", attribute->attrName);
     } else if (!strcmp(attribute->attrName, "saLogRecordDestination")) {
       std::vector<std::string> vstring{};
       for (unsigned i = 0; i < attribute->attrValuesNumber; i++) {
@@ -1641,6 +1678,20 @@ static SaAisErrorT check_attr_validity(
         goto done;
       }
     }
+
+    /* saLogStreamFacilityId
+     *     <= 23
+     */
+    if (i_facilityId_mod) {
+      TRACE("Checking saLogStreamFacilityId");
+      if (i_facilityId > 23) {
+        report_oi_error(immOiHandle, opdata->ccbId, "Invalid facility ID: %u",
+                        i_facilityId);
+        rc = SA_AIS_ERR_BAD_OPERATION;
+        TRACE("Invalid facility ID: %u", i_facilityId);
+        goto done;
+      }
+    }
   }
 
 done:
@@ -2268,6 +2319,10 @@ static SaAisErrorT stream_create_and_configure1(
                          "saLogStreamSeverityFilter")) {
         (*stream)->severityFilter = *((SaUint32T *)value);
         TRACE("severityFilter: %u", (*stream)->severityFilter);
+      } else if (!strcmp(ccb->param.create.attrValues[i]->attrName,
+                         "saLogStreamFacilityId")) {
+        (*stream)->facilityId = *(reinterpret_cast<SaUint32T *>(value));
+        TRACE("facilityId: %u", (*stream)->facilityId);
       } else if (!strcmp(ccb->param.create.attrValues[i]->attrName,
                          "saLogRecordDestination")) {
         std::vector<std::string> vstring{};
@@ -2403,6 +2458,12 @@ static void stream_ccb_apply_modify(const 
CcbUtilOperationData_t *opdata) {
         log_stream_delete_dest_name(stream, dname);
         attrMod = opdata->param.modify.attrMods[i++];
         continue;
+      } else if (!strcmp(attribute->attrName, "saLogStreamFacilityId")) {
+        LOG_NO("%s deleted", __func__);
+        stream->facilityId = 16;
+        new_cfg_file_needed = true;
+        attrMod = opdata->param.modify.attrMods[i++];
+        continue;
       }
     }
 
@@ -2464,6 +2525,11 @@ static void stream_ccb_apply_modify(const 
CcbUtilOperationData_t *opdata) {
         TRACE("%s: stream %s - msgid = %s", __func__, stream->name.c_str(),
               stream->rfc5424MsgId.c_str());
       }
+    } else if (!strcmp(attribute->attrName, "saLogStreamFacilityId")) {
+      if (value != nullptr) {
+        stream->facilityId = *(reinterpret_cast<SaUint32T *>(value));
+        new_cfg_file_needed = true;
+      }
     } else {
       LOG_ER("Error: Unknown attribute name");
       osafassert(0);
@@ -2795,6 +2861,9 @@ static SaAisErrorT stream_create_and_configure(
          */
         stream->creationTimeStamp = *(static_cast<SaTimeT *>(value));
       }
+    } else if (!strcmp(attribute->attrName, "saLogStreamFacilityId")) {
+      stream->facilityId = *(reinterpret_cast<SaUint32T *>(value));
+      TRACE("facilityId: %u", stream->facilityId);
     }
   }
 
@@ -3184,6 +3253,7 @@ int lgs_get_streamobj_attr(SaImmAttrValuesT_2 
***attrib_out,
       const_cast<char *>("saLogStreamLogFileFormat"),
       const_cast<char *>("saLogStreamSeverityFilter"),
       const_cast<char *>("saLogStreamCreationTimestamp"),
+      const_cast<char *>("saLogStreamFacilityId"),
       NULL};
 
   TRACE_ENTER2("object_name_in \"%s\"", object_name_in.c_str());
diff --git a/src/log/logd/lgs_mbcsv.cc b/src/log/logd/lgs_mbcsv.cc
index f83d9ec20..522d7fb6f 100644
--- a/src/log/logd/lgs_mbcsv.cc
+++ b/src/log/logd/lgs_mbcsv.cc
@@ -23,6 +23,7 @@
 
 #include "osaf/immutil/immutil.h"
 #include "log/logd/lgs_dest.h"
+#include "log/logd/lgs_mbcsv_v9.h"
 #include "log/logd/lgs_mbcsv_v6.h"
 #include "log/logd/lgs_mbcsv_v5.h"
 #include "log/logd/lgs_mbcsv_v3.h"
@@ -141,7 +142,96 @@ uint32_t edp_ed_open_stream_rec(EDU_HDL *edu_hdl, EDU_TKN 
*edu_tkn,
   uint32_t rc = NCSCC_RC_SUCCESS;
   lgs_ckpt_stream_open_t *ckpt_open_stream_msg_ptr = NULL,
                          **ckpt_open_stream_msg_dec_ptr;
-  if (lgs_is_peer_v6()) {
+  if (lgs_is_peer_v9()) {
+    EDU_INST_SET ckpt_open_stream_rec_ed_rules[] = {
+        {EDU_START, edp_ed_open_stream_rec, 0, 0, 0,
+         sizeof(lgs_ckpt_stream_open_t), 0, NULL},
+        {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+         (int64_t) & (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->streamId,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+         (int64_t) & (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->clientId,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+         (int64_t) & (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->logFile,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+         (int64_t) & (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->logPath,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->logFileCurrent,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->dest_names,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_uns64, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->maxFileSize,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_int32, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->maxLogRecordSize,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_int32, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t 
*>(0))->logFileFullAction,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_int32, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->maxFilesRotated,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+         (int64_t) & (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->fileFmt,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->logStreamName,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_uns64, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t 
*>(0))->creationTimeStamp,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->numOpeners,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->streamType,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->logRecordId,
+         0, NULL},
+        {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+         (int64_t) &
+             (reinterpret_cast<lgs_ckpt_stream_open_t *>(0))->facilityId,
+         0, NULL},
+        {EDU_END, 0, 0, 0, 0, 0, 0, NULL},
+    };
+
+    if (op == EDP_OP_TYPE_ENC) {
+      ckpt_open_stream_msg_ptr = static_cast<lgs_ckpt_stream_open_t *>(ptr);
+    } else if (op == EDP_OP_TYPE_DEC) {
+      ckpt_open_stream_msg_dec_ptr =
+          static_cast<lgs_ckpt_stream_open_t **>(ptr);
+      if (*ckpt_open_stream_msg_dec_ptr == NULL) {
+        *o_err = EDU_ERR_MEM_FAIL;
+        return NCSCC_RC_FAILURE;
+      }
+      memset(*ckpt_open_stream_msg_dec_ptr, '\0',
+             sizeof(lgs_ckpt_stream_open_t));
+      ckpt_open_stream_msg_ptr = *ckpt_open_stream_msg_dec_ptr;
+    } else {
+      ckpt_open_stream_msg_ptr = static_cast<lgs_ckpt_stream_open_t *>(ptr);
+    }
+
+    rc = m_NCS_EDU_RUN_RULES(edu_hdl, edu_tkn, ckpt_open_stream_rec_ed_rules,
+                             ckpt_open_stream_msg_ptr, ptr_data_len, buf_env,
+                             op, o_err);
+  } else if (lgs_is_peer_v6()) {
     EDU_INST_SET ckpt_open_stream_rec_ed_rules[] = {
         {EDU_START, edp_ed_open_stream_rec, 0, 0, 0,
          sizeof(lgs_ckpt_stream_open_t), 0, NULL},
@@ -491,6 +581,18 @@ bool lgs_is_peer_v8() {
   }
 }
 
+/**
+ * Check if peer is version 9 (or later)
+ * @return bool
+ */
+bool lgs_is_peer_v9() {
+  if (lgs_cb->mbcsv_peer_version >= LGS_MBCSV_VERSION_9) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
 /**
  * Check if configured for split file system.
  * If other node is version 1 split file system mode is not applicable.
@@ -736,6 +838,7 @@ void lgs_ckpt_stream_open_set(log_stream_t *logStream,
   stream_open->maxFilesRotated = logStream->maxFilesRotated;
   stream_open->creationTimeStamp = logStream->creationTimeStamp;
   stream_open->numOpeners = logStream->numOpeners;
+  stream_open->facilityId = logStream->facilityId;
 
   if (lgs_is_peer_v7() == true) {
     stream_open->streamType = logStream->streamType;
@@ -908,6 +1011,7 @@ static uint32_t edu_enc_reg_list(lgs_cb_t *cb, NCS_UBAID 
*uba) {
 
 static uint32_t ckpt_encode_async_update(lgs_cb_t *lgs_cb, EDU_HDL edu_hdl,
                                          NCS_MBCSV_CB_ARG *cbk_arg) {
+  lgsv_ckpt_msg_v9_t *data_v9 = NULL;
   lgsv_ckpt_msg_v8_t *data_v8 = NULL;
   lgsv_ckpt_msg_v6_t *data_v6 = NULL;
   lgsv_ckpt_msg_v5_t *data_v5 = NULL;
@@ -921,7 +1025,12 @@ static uint32_t ckpt_encode_async_update(lgs_cb_t 
*lgs_cb, EDU_HDL edu_hdl,
 
   TRACE_ENTER();
   /* Set reo_hdl from callback arg to ckpt_rec */
-  if (lgs_is_peer_v8()) {
+  if (lgs_is_peer_v9()) {
+    data_v9 = reinterpret_cast<lgsv_ckpt_msg_v9_t *>(
+        static_cast<int64_t>(cbk_arg->info.encode.io_reo_hdl));
+    vdata = data_v9;
+    edp_function = edp_ed_ckpt_msg_v9;
+  } else if (lgs_is_peer_v8()) {
     data_v8 = reinterpret_cast<lgsv_ckpt_msg_v8_t *>(
         static_cast<long>(cbk_arg->info.encode.io_reo_hdl));
     vdata = data_v8;
@@ -1250,7 +1359,12 @@ static uint32_t ckpt_decode_log_cfg_stream(lgs_cb_t *cb, 
void *ckpt_msg,
   void *stream_cfg;
   EDU_PROG_HANDLER edp_function;
 
-  if (lgs_is_peer_v8()) {
+  if (lgs_is_peer_v9()) {
+    lgsv_ckpt_msg_v9_t *ckpt_msg_v9 =
+        static_cast<lgsv_ckpt_msg_v9_t *>(ckpt_msg);
+    stream_cfg = &ckpt_msg_v9->ckpt_rec.stream_cfg;
+    edp_function = edp_ed_cfg_stream_rec_v9;
+  } else if (lgs_is_peer_v8()) {
     lgsv_ckpt_msg_v8_t *ckpt_msg_v8 =
         static_cast<lgsv_ckpt_msg_v8_t *>(ckpt_msg);
     stream_cfg = &ckpt_msg_v8->ckpt_rec.stream_cfg;
@@ -1341,6 +1455,8 @@ static uint32_t ckpt_decode_async_update(lgs_cb_t *cb,
   lgsv_ckpt_msg_v6_t *ckpt_msg_v6 = &msg_v6;
   lgsv_ckpt_msg_v8_t msg_v8;
   lgsv_ckpt_msg_v8_t *ckpt_msg_v8 = &msg_v8;
+  lgsv_ckpt_msg_v9_t msg_v9;
+  lgsv_ckpt_msg_v9_t *ckpt_msg_v9 = &msg_v9;
   void *ckpt_msg;
   lgsv_ckpt_header_t hdr, *hdr_ptr = &hdr;
 
@@ -1361,7 +1477,10 @@ static uint32_t ckpt_decode_async_update(lgs_cb_t *cb,
 
   TRACE_2("\tckpt_rec_type: %d ", (int)hdr_ptr->ckpt_rec_type);
 
-  if (lgs_is_peer_v8()) {
+  if (lgs_is_peer_v9()) {
+    ckpt_msg_v9->header = hdr;
+    ckpt_msg = ckpt_msg_v9;
+  } else if (lgs_is_peer_v8()) {
     ckpt_msg_v8->header = hdr;
     ckpt_msg = ckpt_msg_v8;
   } else if (lgs_is_peer_v6()) {
@@ -1385,7 +1504,10 @@ static uint32_t ckpt_decode_async_update(lgs_cb_t *cb,
   switch (hdr_ptr->ckpt_rec_type) {
     case LGS_CKPT_CLIENT_INITIALIZE:
       TRACE_2("\tINITIALIZE REC: UPDATE");
-      if (lgs_is_peer_v8()) {
+      if (lgs_is_peer_v9()) {
+        reg_rec = &ckpt_msg_v9->ckpt_rec.initialize_client;
+        edp_function_reg = edp_ed_reg_rec_v6;
+      } else if (lgs_is_peer_v8()) {
         reg_rec = &ckpt_msg_v8->ckpt_rec.initialize_client;
         edp_function_reg = edp_ed_reg_rec_v6;
       } else if (lgs_is_peer_v6()) {
@@ -1421,7 +1543,9 @@ static uint32_t ckpt_decode_async_update(lgs_cb_t *cb,
 
     case LGS_CKPT_OPEN_STREAM: /* 4 */
       TRACE_2("\tSTREAM OPEN: UPDATE");
-      if (lgs_is_peer_v8()) {
+      if (lgs_is_peer_v9()) {
+        stream_open = &ckpt_msg_v9->ckpt_rec.stream_open;
+      } else if (lgs_is_peer_v8()) {
         stream_open = &ckpt_msg_v8->ckpt_rec.stream_open;
       } else if (lgs_is_peer_v6()) {
         stream_open = &ckpt_msg_v6->ckpt_rec.stream_open;
@@ -1542,6 +1666,7 @@ static uint32_t ckpt_decode_cold_sync(lgs_cb_t *cb, 
NCS_MBCSV_CB_ARG *cbk_arg) {
   lgsv_ckpt_msg_v2_t msg_v2;
   lgsv_ckpt_msg_v6_t msg_v6;
   lgsv_ckpt_msg_v8_t msg_v8;
+  lgsv_ckpt_msg_v9_t msg_v9;
   uint32_t num_rec = 0;
   void *reg_rec = NULL;
   lgs_ckpt_stream_open_t *stream_rec = NULL;
@@ -1563,7 +1688,16 @@ static uint32_t ckpt_decode_cold_sync(lgs_cb_t *cb, 
NCS_MBCSV_CB_ARG *cbk_arg) {
      | Header|RegRecords1..n|Header|streamRecords1..n|
      -------------------------------------------------
   */
-  if (lgs_is_peer_v8()) {
+  if (lgs_is_peer_v9()) {
+    lgsv_ckpt_msg_v9_t *data_v9 = &msg_v9;
+    header = &data_v9->header;
+    initialize_client_rec_ptr = &data_v9->ckpt_rec.initialize_client;
+    stream_open_rec_ptr = &data_v9->ckpt_rec.stream_open;
+    vdata = data_v9;
+    vckpt_rec = &data_v9->ckpt_rec;
+    ckpt_rec_size = sizeof(data_v9->ckpt_rec);
+    edp_function_reg = edp_ed_reg_rec_v6;
+  } else if (lgs_is_peer_v8()) {
     lgsv_ckpt_msg_v8_t *data_v8 = &msg_v8;
     header = &data_v8->header;
     initialize_client_rec_ptr = &data_v8->ckpt_rec.initialize_client;
@@ -1725,13 +1859,17 @@ uint32_t process_ckpt_data(lgs_cb_t *cb, void *data) {
   lgsv_ckpt_msg_v5_t *data_v5;
   lgsv_ckpt_msg_v6_t *data_v6;
   lgsv_ckpt_msg_v8_t *data_v8;
+  lgsv_ckpt_msg_v9_t *data_v9;
 
   if ((!cb) || (data == NULL)) {
     TRACE("%s - FAILED: (!cb) || (data == NULL)", __FUNCTION__);
     return (rc = NCSCC_RC_FAILURE);
   }
 
-  if (lgs_is_peer_v8()) {
+  if (lgs_is_peer_v9()) {
+    data_v9 = static_cast<lgsv_ckpt_msg_v9_t *>(data);
+    lgsv_ckpt_msg_type = data_v9->header.ckpt_rec_type;
+  } else if (lgs_is_peer_v8()) {
     data_v8 = static_cast<lgsv_ckpt_msg_v8_t *>(data);
     lgsv_ckpt_msg_type = data_v8->header.ckpt_rec_type;
   } else if (lgs_is_peer_v6()) {
@@ -2230,7 +2368,10 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t *cb, void *data) 
{
 
   TRACE_ENTER();
 
-  if (lgs_is_peer_v8()) {
+  if (lgs_is_peer_v9()) {
+    lgsv_ckpt_msg_v9_t *data_v9 = static_cast<lgsv_ckpt_msg_v9_t *>(data);
+    param = &data_v9->ckpt_rec.stream_open;
+  } else if (lgs_is_peer_v8()) {
     lgsv_ckpt_msg_v8_t *data_v8 = static_cast<lgsv_ckpt_msg_v8_t *>(data);
     param = &data_v8->ckpt_rec.stream_open;
   } else if (lgs_is_peer_v6()) {
@@ -2289,6 +2430,7 @@ uint32_t ckpt_proc_open_stream(lgs_cb_t *cb, void *data) {
     stream->logFileCurrent = param->logFileCurrent;
     stream->stb_prev_actlogFileCurrent = param->logFileCurrent;
     stream->stb_logFileCurrent = param->logFileCurrent;
+    stream->facilityId = param->facilityId;
 
     if (stream->streamType == STREAM_TYPE_APPLICATION) {
       // Note: Previous handling for backwards compatibility
@@ -2497,10 +2639,27 @@ static uint32_t ckpt_proc_cfg_stream(lgs_cb_t *cb, void 
*data) {
   SaUint32T severityFilter;
   char *logFileCurrent;
   bool new_cfg_file_needed = false;
+  uint32_t facilityId = 16;
 
   TRACE_ENTER();
 
-  if (lgs_is_peer_v8()) {
+  if (lgs_is_peer_v9()) {
+    lgsv_ckpt_msg_v9_t *data_v9 = static_cast<lgsv_ckpt_msg_v9_t *>(data);
+    name = data_v9->ckpt_rec.stream_cfg.name;
+    fileName = data_v9->ckpt_rec.stream_cfg.fileName;
+    pathName = data_v9->ckpt_rec.stream_cfg.pathName;
+    maxLogFileSize = data_v9->ckpt_rec.stream_cfg.maxLogFileSize;
+    fixedLogRecordSize = data_v9->ckpt_rec.stream_cfg.fixedLogRecordSize;
+    logFullAction = data_v9->ckpt_rec.stream_cfg.logFullAction;
+    logFullHaltThreshold = data_v9->ckpt_rec.stream_cfg.logFullHaltThreshold;
+    maxFilesRotated = data_v9->ckpt_rec.stream_cfg.maxFilesRotated;
+    logFileFormat = data_v9->ckpt_rec.stream_cfg.logFileFormat;
+    severityFilter = data_v9->ckpt_rec.stream_cfg.severityFilter;
+    logFileCurrent = data_v9->ckpt_rec.stream_cfg.logFileCurrent;
+    dest_names = data_v9->ckpt_rec.stream_cfg.dest_names;
+    closetime = data_v9->ckpt_rec.stream_cfg.c_file_close_time_stamp;
+    facilityId = data_v9->ckpt_rec.stream_cfg.facilityId;
+  } else if (lgs_is_peer_v8()) {
     lgsv_ckpt_msg_v8_t *data_v8 = static_cast<lgsv_ckpt_msg_v8_t *>(data);
     name = data_v8->ckpt_rec.stream_cfg.name;
     fileName = data_v8->ckpt_rec.stream_cfg.fileName;
@@ -2571,6 +2730,7 @@ static uint32_t ckpt_proc_cfg_stream(lgs_cb_t *cb, void 
*data) {
       (stream->logFullAction != logFullAction) ||
       (stream->maxFilesRotated != maxFilesRotated) ||
       (strcmp(stream->logFileFormat, logFileFormat) != 0) ||
+      (stream->facilityId != facilityId) ||
       (stream->fileName != fileName))
     new_cfg_file_needed = true;
 
@@ -2581,6 +2741,7 @@ static uint32_t ckpt_proc_cfg_stream(lgs_cb_t *cb, void 
*data) {
   stream->logFullAction = logFullAction;
   stream->logFullHaltThreshold = logFullHaltThreshold;
   stream->maxFilesRotated = maxFilesRotated;
+  stream->facilityId = facilityId;
 
   if (stream->logFileFormat != NULL) {
     free(stream->logFileFormat);
@@ -2690,7 +2851,11 @@ uint32_t lgs_ckpt_send_async(lgs_cb_t *cb, void 
*ckpt_rec, uint32_t action) {
 
   TRACE_ENTER();
 
-  if (lgs_is_peer_v8()) {
+  if (lgs_is_peer_v9()) {
+    lgsv_ckpt_msg_v9_t *ckpt_rec_v9 =
+        static_cast<lgsv_ckpt_msg_v9_t *>(ckpt_rec);
+    ckpt_rec_type = ckpt_rec_v9->header.ckpt_rec_type;
+  } else if (lgs_is_peer_v8()) {
     lgsv_ckpt_msg_v8_t *ckpt_rec_v8 =
         static_cast<lgsv_ckpt_msg_v8_t *>(ckpt_rec);
     ckpt_rec_type = ckpt_rec_v8->header.ckpt_rec_type;
diff --git a/src/log/logd/lgs_mbcsv.h b/src/log/logd/lgs_mbcsv.h
index 998e843e4..02db433f2 100644
--- a/src/log/logd/lgs_mbcsv.h
+++ b/src/log/logd/lgs_mbcsv.h
@@ -43,9 +43,10 @@
 #define LGS_MBCSV_VERSION_6 6
 #define LGS_MBCSV_VERSION_7 7
 #define LGS_MBCSV_VERSION_8 8
+#define LGS_MBCSV_VERSION_9 9
 
 /* Current version */
-#define LGS_MBCSV_VERSION 8
+#define LGS_MBCSV_VERSION 9
 #define LGS_MBCSV_VERSION_MIN 1
 
 /* Checkpoint message types(Used as 'reotype' w.r.t mbcsv)  */
@@ -108,6 +109,7 @@ typedef struct {
   char *dest_names;
   logStreamTypeT streamType;
   uint32_t logRecordId; /* log record identifier increased for each record */
+  uint32_t facilityId;
 } lgs_ckpt_stream_open_t;
 
 uint32_t lgs_mbcsv_init(lgs_cb_t *lgs_cb, SaAmfHAStateT ha_state);
@@ -121,6 +123,7 @@ bool lgs_is_peer_v6();
 // lgs_ckpt_stream_open_t structure
 bool lgs_is_peer_v7();
 bool lgs_is_peer_v8();
+bool lgs_is_peer_v9();
 
 bool lgs_is_split_file_system();
 uint32_t lgs_mbcsv_dispatch(NCS_MBCSV_HDL mbcsv_hdl);
diff --git a/src/log/logd/lgs_mbcsv_v9.cc b/src/log/logd/lgs_mbcsv_v9.cc
new file mode 100644
index 000000000..61b5f431c
--- /dev/null
+++ b/src/log/logd/lgs_mbcsv_v9.cc
@@ -0,0 +1,243 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2020 The OpenSAF Foundation
+ * Copyright Ericsson AB 2020 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#include "log/logd/lgs_mbcsv_v9.h"
+#include "base/logtrace.h"
+
+/****************************************************************************
+ * Name          : edp_ed_cfg_stream_rec
+ *
+ * Description   : This function is an EDU program for encoding/decoding
+ *                 lgsv checkpoint cfg_update_stream log rec.
+ *
+ * Arguments     : EDU_HDL - pointer to edu handle,
+ *                 EDU_TKN - internal edu token to help encode/decode,
+ *                 POINTER to the structure to encode/decode from/to,
+ *                 data length specifying number of structures,
+ *                 EDU_BUF_ENV - pointer to buffer for encoding/decoding.
+ *                 op - operation type being encode/decode.
+ *                 EDU_ERR - out param to indicate errors in processing.
+ *
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ *
+ * Notes         : None.
+ *****************************************************************************/
+
+uint32_t edp_ed_cfg_stream_rec_v9(EDU_HDL *edu_hdl, EDU_TKN *edu_tkn,
+                                  NCSCONTEXT ptr, uint32_t *ptr_data_len,
+                                  EDU_BUF_ENV *buf_env, EDP_OP_TYPE op,
+                                  EDU_ERR *o_err) {
+  uint32_t rc = NCSCC_RC_SUCCESS;
+  lgs_ckpt_stream_cfg_v4_t *ckpt_stream_cfg_msg_ptr = NULL,
+                           **ckpt_stream_cfg_msg_dec_ptr;
+  TRACE_ENTER();
+  EDU_INST_SET ckpt_stream_cfg_rec_ed_rules[] = {
+      {EDU_START, edp_ed_cfg_stream_rec_v9, 0, 0, 0,
+       sizeof(lgs_ckpt_stream_cfg_v4_t), 0, NULL},
+      {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+       (int64_t) & (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->name, 0,
+       NULL},
+      {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+       (int64_t) & (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->fileName,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+       (int64_t) & (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->pathName,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_uns64, 0, 0, 0,
+       (int64_t) &
+           (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->maxLogFileSize,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+       (int64_t) & (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))
+                       ->fixedLogRecordSize,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+       (int64_t) &
+           (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->haProperty,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+       (int64_t) &
+           (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->logFullAction,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+       (int64_t) & (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))
+                       ->logFullHaltThreshold,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+       (int64_t) &
+           (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->maxFilesRotated,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+       (int64_t) &
+           (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->logFileFormat,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+       (int64_t) &
+           (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->severityFilter,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+       (int64_t) &
+           (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->logFileCurrent,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_string, 0, 0, 0,
+       (int64_t) &
+           (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->dest_names,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_uns64, 0, 0, 0,
+       (int64_t) & (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))
+                       ->c_file_close_time_stamp,
+       0, NULL},
+      {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+       (int64_t) &
+           (reinterpret_cast<lgs_ckpt_stream_cfg_v4_t *>(0))->facilityId,
+       0, NULL},
+      {EDU_END, 0, 0, 0, 0, 0, 0, NULL},
+  };
+
+  if (op == EDP_OP_TYPE_ENC) {
+    ckpt_stream_cfg_msg_ptr = static_cast<lgs_ckpt_stream_cfg_v4_t *>(ptr);
+  } else if (op == EDP_OP_TYPE_DEC) {
+    ckpt_stream_cfg_msg_dec_ptr = static_cast<lgs_ckpt_stream_cfg_v4_t 
**>(ptr);
+    if (*ckpt_stream_cfg_msg_dec_ptr == NULL) {
+      *o_err = EDU_ERR_MEM_FAIL;
+      return NCSCC_RC_FAILURE;
+    }
+    memset(*ckpt_stream_cfg_msg_dec_ptr, '\0',
+           sizeof(lgs_ckpt_stream_cfg_v4_t));
+    ckpt_stream_cfg_msg_ptr = *ckpt_stream_cfg_msg_dec_ptr;
+  } else {
+    ckpt_stream_cfg_msg_ptr = static_cast<lgs_ckpt_stream_cfg_v4_t *>(ptr);
+  }
+
+  rc = m_NCS_EDU_RUN_RULES(edu_hdl, edu_tkn, ckpt_stream_cfg_rec_ed_rules,
+                           ckpt_stream_cfg_msg_ptr, ptr_data_len, buf_env, op,
+                           o_err);
+  TRACE_LEAVE();
+  return rc;
+}
+
+/****************************************************************************
+ * Name          : edp_ed_ckpt_msg_v9
+ *
+ * Description   : This function is an EDU program for encoding/decoding
+ *                 lgsv checkpoint messages. This program runs the
+ *                 edp_ed_hdr_rec program first to decide the
+ *                 checkpoint message type based on which it will call the
+ *                 appropriate EDU programs for the different checkpoint
+ *                 messages.
+ *
+ * Arguments     : EDU_HDL - pointer to edu handle,
+ *                 EDU_TKN - internal edu token to help encode/decode,
+ *                 POINTER to the structure to encode/decode from/to,
+ *                 data length specifying number of structures,
+ *                 EDU_BUF_ENV - pointer to buffer for encoding/decoding.
+ *                 op - operation type being encode/decode.
+ *                 EDU_ERR - out param to indicate errors in processing.
+ *
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ *
+ * Notes         : None.
+ *****************************************************************************/
+
+uint32_t edp_ed_ckpt_msg_v9(EDU_HDL *edu_hdl, EDU_TKN *edu_tkn, NCSCONTEXT ptr,
+                            uint32_t *ptr_data_len, EDU_BUF_ENV *buf_env,
+                            EDP_OP_TYPE op, EDU_ERR *o_err) {
+  uint32_t rc = NCSCC_RC_SUCCESS;
+  lgsv_ckpt_msg_v9_t *ckpt_msg_ptr = NULL, **ckpt_msg_dec_ptr;
+  TRACE_ENTER();
+  EDU_INST_SET ckpt_msg_ed_rules[] = {
+      {EDU_START, edp_ed_ckpt_msg_v9, 0, 0, 0, sizeof(lgsv_ckpt_msg_v9_t), 0,
+       NULL},
+      {EDU_EXEC, edp_ed_header_rec, 0, 0, 0,
+       (int64_t) & (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))->header, 0,
+       NULL},
+
+      {EDU_TEST, ncs_edp_uns32, 0, 0, 0,
+       (int64_t) & (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))->header, 0,
+       (EDU_EXEC_RTINE)ckpt_msg_test_type},
+
+      /* Reg Record */
+      {EDU_EXEC, edp_ed_reg_rec_v6, 0, 0, static_cast<int>(EDU_EXIT),
+       (int64_t) & (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))
+                       ->ckpt_rec.initialize_client,
+       0, NULL},
+
+      /* Finalize record */
+      {EDU_EXEC, edp_ed_finalize_rec_v2, 0, 0, static_cast<int>(EDU_EXIT),
+       (int64_t) & (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))
+                       ->ckpt_rec.finalize_client,
+       0, NULL},
+
+      /* write log Record */
+      {EDU_EXEC, edp_ed_write_rec_v2, 0, 0, static_cast<int>(EDU_EXIT),
+       (int64_t) &
+           (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))->ckpt_rec.write_log,
+       0, NULL},
+
+      /* Open stream */
+      {EDU_EXEC, edp_ed_open_stream_rec, 0, 0, static_cast<int>(EDU_EXIT),
+       (int64_t) &
+           (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))->ckpt_rec.stream_open,
+       0, NULL},
+
+      /* Close stream */
+      {EDU_EXEC, edp_ed_close_stream_rec_v2, 0, 0, static_cast<int>(EDU_EXIT),
+       (int64_t) &
+           (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))->ckpt_rec.stream_close,
+       0, NULL},
+
+      /* Agent dest */
+      {EDU_EXEC, edp_ed_agent_down_rec_v2, 0, 0, static_cast<int>(EDU_EXIT),
+       (int64_t) &
+           (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))->ckpt_rec.stream_cfg,
+       0, NULL},
+
+      /* Cfg stream */
+      {EDU_EXEC, edp_ed_cfg_stream_rec_v9, 0, 0, static_cast<int>(EDU_EXIT),
+       (int64_t) &
+           (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))->ckpt_rec.stream_cfg,
+       0, NULL},
+
+      /* Lgs cfg */
+      {EDU_EXEC, edp_ed_lgs_cfg_rec_v5, 0, 0, static_cast<int>(EDU_EXIT),
+       (int64_t) &
+           (reinterpret_cast<lgsv_ckpt_msg_v9_t *>(0))->ckpt_rec.lgs_cfg,
+       0, NULL},
+
+      {EDU_END, 0, 0, 0, 0, 0, 0, NULL},
+  };
+
+  if (op == EDP_OP_TYPE_ENC) {
+    ckpt_msg_ptr = static_cast<lgsv_ckpt_msg_v9_t *>(ptr);
+  } else if (op == EDP_OP_TYPE_DEC) {
+    ckpt_msg_dec_ptr = static_cast<lgsv_ckpt_msg_v9_t **>(ptr);
+    if (*ckpt_msg_dec_ptr == NULL) {
+      *o_err = EDU_ERR_MEM_FAIL;
+      return NCSCC_RC_FAILURE;
+    }
+    memset(*ckpt_msg_dec_ptr, '\0', sizeof(lgsv_ckpt_msg_v9_t));
+    ckpt_msg_ptr = *ckpt_msg_dec_ptr;
+  } else {
+    ckpt_msg_ptr = static_cast<lgsv_ckpt_msg_v9_t *>(ptr);
+  }
+
+  rc = m_NCS_EDU_RUN_RULES(edu_hdl, edu_tkn, ckpt_msg_ed_rules, ckpt_msg_ptr,
+                           ptr_data_len, buf_env, op, o_err);
+  TRACE_LEAVE();
+  return rc;
+}
diff --git a/src/log/logd/lgs_mbcsv_v9.h b/src/log/logd/lgs_mbcsv_v9.h
new file mode 100644
index 000000000..7c3ef9722
--- /dev/null
+++ b/src/log/logd/lgs_mbcsv_v9.h
@@ -0,0 +1,67 @@
+/*      -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2020 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef LOG_LOGD_LGS_MBCSV_V9_H_
+#define LOG_LOGD_LGS_MBCSV_V9_H_
+
+#include "log/logd/lgs.h"
+#include "log/logd/lgs_config.h"
+#include "log/logd/lgs_mbcsv_v2.h"
+#include "log/logd/lgs_mbcsv_v5.h"
+#include "log/logd/lgs_mbcsv_v6.h"
+
+typedef struct {
+  char *name;
+  char *fileName;
+  char *pathName;
+  SaUint64T maxLogFileSize;
+  SaUint32T fixedLogRecordSize;
+  SaBoolT haProperty; /* app log stream only */
+  SaLogFileFullActionT logFullAction;
+  SaUint32T logFullHaltThreshold; /* !app log stream */
+  SaUint32T maxFilesRotated;
+  char *logFileFormat;
+  SaUint32T severityFilter;
+  char *logFileCurrent;
+  char *dest_names;
+  uint64_t c_file_close_time_stamp; /* Time in sec for file rename on Active */
+  uint32_t facilityId;
+} lgs_ckpt_stream_cfg_v4_t;
+
+typedef struct {
+  lgsv_ckpt_header_t header;
+  union {
+    lgs_ckpt_initialize_msg_v6_t initialize_client;
+    lgs_ckpt_finalize_msg_v2_t finalize_client;
+    lgs_ckpt_write_log_v2_t write_log;
+    lgs_ckpt_agent_down_v2_t agent_down;
+    lgs_ckpt_stream_open_t stream_open;
+    lgs_ckpt_stream_close_v2_t stream_close;
+    lgs_ckpt_stream_cfg_v4_t stream_cfg;
+    lgs_ckpt_lgs_cfg_v5_t lgs_cfg;
+  } ckpt_rec;
+} lgsv_ckpt_msg_v9_t;
+
+uint32_t edp_ed_cfg_stream_rec_v9(EDU_HDL *edu_hdl, EDU_TKN *edu_tkn,
+                                  NCSCONTEXT ptr, uint32_t *ptr_data_len,
+                                  EDU_BUF_ENV *buf_env, EDP_OP_TYPE op,
+                                  EDU_ERR *o_err);
+uint32_t edp_ed_ckpt_msg_v9(EDU_HDL *edu_hdl, EDU_TKN *edu_tkn, NCSCONTEXT ptr,
+                            uint32_t *ptr_data_len, EDU_BUF_ENV *buf_env,
+                            EDP_OP_TYPE op, EDU_ERR *o_err);
+
+#endif  // LOG_LOGD_LGS_MBCSV_V9_H_
diff --git a/src/log/logd/lgs_recov.cc b/src/log/logd/lgs_recov.cc
index 7c0197b7f..c5f35885c 100644
--- a/src/log/logd/lgs_recov.cc
+++ b/src/log/logd/lgs_recov.cc
@@ -320,6 +320,7 @@ int lgs_restore_one_app_stream(const std::string 
&stream_name,
   log_stream_t *log_stream = nullptr;
   SaTimeT restored_creationTimeStamp = 0;
   SaUint32T restored_severityFilter = 0;
+  SaUint32T restored_facilityId = 16;
 
   std::string fileName;
   std::string pathName, fullPathName;
@@ -501,6 +502,14 @@ int lgs_restore_one_app_stream(const std::string 
&stream_name,
       }
       restored_severityFilter = *(static_cast<SaUint32T *>(value));
       TRACE("\t saLogStreamSeverityFilter=%d", restored_severityFilter);
+    } else if (!strcmp(name, "saLogStreamFacilityId")) {
+      if (value == nullptr) {
+        TRACE("%s: Fail, has empty value", name);
+        rc_out = -1;
+        goto done_free_attr;
+      }
+      restored_facilityId = *(static_cast<SaUint32T *>(value));
+      TRACE("\t saLogStreamFacilityId=%d", restored_facilityId);
     }
   }
 
@@ -567,6 +576,7 @@ int lgs_restore_one_app_stream(const std::string 
&stream_name,
   log_stream->severityFilter = restored_severityFilter;
   log_stream->filtered = 0;
   log_stream->isRtStream = SA_TRUE;
+  log_stream->facilityId = restored_facilityId;
 
   TRACE("\t Stream obj attributes handled and stream is created");
 
diff --git a/src/log/logd/lgs_stream.cc b/src/log/logd/lgs_stream.cc
index f2f7df940..71782f7ea 100644
--- a/src/log/logd/lgs_stream.cc
+++ b/src/log/logd/lgs_stream.cc
@@ -418,6 +418,7 @@ void log_stream_print(log_stream_t *stream) {
   TRACE_2("  filtered:             %llu", stream->filtered);
   TRACE_2("  stb_dest_names:       %s", stream->stb_dest_names.c_str());
   TRACE_2("  isRtStream:           %d", stream->isRtStream);
+  TRACE_2("  facilityId:           %u", stream->facilityId);
 }
 
 /**
@@ -665,6 +666,12 @@ SaAisErrorT lgs_create_appstream_rt_object(log_stream_t 
*const stream) {
         .attrValueType = SA_IMM_ATTR_SATIMET,
         .attrValuesNumber = 1,
         .attrValues = arr11};
+    void *arr12[] = {&stream->facilityId};
+    const SaImmAttrValuesT_2 attr_saLogStreamFacilityId = {
+        .attrName = const_cast<SaImmAttrNameT>("saLogStreamFacilityId"),
+        .attrValueType = SA_IMM_ATTR_SAUINT32T,
+        .attrValuesNumber = 1,
+        .attrValues = arr12};
     const SaImmAttrValuesT_2 *attrValues[] = {
         &attr_safLgStr,
         &attr_safLogStreamFileName,
@@ -677,6 +684,7 @@ SaAisErrorT lgs_create_appstream_rt_object(log_stream_t 
*const stream) {
         &attr_saLogStreamLogFileFormat,
         &attr_saLogStreamSeverityFilter,
         &attr_saLogStreamCreationTimestamp,
+        &attr_saLogStreamFacilityId,
         NULL};
 
     SaNameT object_name;
@@ -723,6 +731,7 @@ log_stream_t *log_stream_new(const std::string &name, int 
stream_id) {
   stream->severityFilter = 0x7f; /* by default all levels are allowed */
   stream->isRtStream = SA_FALSE;
   stream->dest_names.clear();
+  stream->facilityId = 16;
 
   /* Initiate local or shared stream file descriptor dependant on shared or
    * split file system
diff --git a/src/log/logd/lgs_stream.h b/src/log/logd/lgs_stream.h
index 8fdb5693d..a9659582b 100644
--- a/src/log/logd/lgs_stream.h
+++ b/src/log/logd/lgs_stream.h
@@ -53,6 +53,7 @@ typedef struct log_stream {
   SaUint32T numOpeners;
   SaUint64T filtered; /* discarded by server due to filtering */
   std::string rfc5424MsgId;
+  uint32_t facilityId;
   /* --- end correspond to IMM Class --- */
 
   uint32_t streamId; /* The unique stream id for this stream */
diff --git a/src/log/logd/lgs_unixsock_dest.cc 
b/src/log/logd/lgs_unixsock_dest.cc
index a48250063..cee3abbf5 100644
--- a/src/log/logd/lgs_unixsock_dest.cc
+++ b/src/log/logd/lgs_unixsock_dest.cc
@@ -70,13 +70,16 @@ void UnixSocketHandler::Open() { FlushStatus(); }
 
 void UnixSocketHandler::FormRfc5424(const DestinationHandler::RecordInfo& msg,
                                     RfcBuffer* buf) {
+  base::LogMessage::Facility facilityId =
+      (msg.facilityId < 24)
+          ? static_cast<base::LogMessage::Facility>(msg.facilityId)
+          : base::LogMessage::Facility::kLocal0;
   base::LogMessage::Severity sev{Sev(msg.severity)};
   base::LogMessage::HostName hostname{msg.origin};
   base::LogMessage::ProcId procid{""};
   base::LogMessage::AppName appname{msg.app_name};
 
-  base::LogMessage::Write(base::LogMessage::Facility::kLocal0, sev, msg.time,
-                          hostname, appname, procid,
+  base::LogMessage::Write(facilityId, sev, msg.time, hostname, appname, procid,
                           base::LogMessage::MsgId{msg.msgid}, {},
                           std::string{msg.log_record}, buf);
 }
diff --git a/src/log/tests/lgs_dest_test.cc b/src/log/tests/lgs_dest_test.cc
index 3f1b90e57..6ef27ac0d 100644
--- a/src/log/tests/lgs_dest_test.cc
+++ b/src/log/tests/lgs_dest_test.cc
@@ -147,6 +147,7 @@ static const char rec[] = "hello world";
 static const char hostname[] = "sc-1";
 static const char networkname[] = "networkA";
 static const uint16_t sev = 3;
+static const uint32_t facilityId = 4;
 static const char appname[] = "lgs_dest_test";
 static const char dn[] = "safLgStrCfg=test";
 static const char msgid[] = "testC";
@@ -162,6 +163,7 @@ void initData(RecordData* data) {
   data->recordId = 1;
   data->sev = 3;
   data->time = base::ReadRealtimeClock();
+  data->facilityId = facilityId;
 }
 
 // No destination name & no destination configuration exist
@@ -258,6 +260,7 @@ TEST(WriteToDestination, HaveDestNameAndDestCfg) {
   info.severity = data.sev;
   info.time = data.time;
   info.origin = origin.c_str();
+  info.facilityId = data.facilityId;
 
   WriteToDestination(data, {"test"});
 
-- 
2.17.1



_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to