From a75b29e047eadf8e80046ebbf0e0663376b94337 Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Mon, 16 Aug 2021 20:43:37 +0200
Subject: [PATCH] update project

---
 agent_based/checkpoint_fw_ls.py          |  58 ++++----
 agent_based/checkpoint_fwm_ls.py         | 181 +++++++----------------
 checkpoint_log_server.mkp                | Bin 7201 -> 6692 bytes
 packages/checkpoint_log_server           |   2 +-
 web/plugins/metrics/checkpoint_fw_log.py |  78 +++++-----
 web/plugins/wato/checkpoint_fw_ls.py     |   2 +-
 6 files changed, 126 insertions(+), 195 deletions(-)

diff --git a/agent_based/checkpoint_fw_ls.py b/agent_based/checkpoint_fw_ls.py
index 4357428..6aeda58 100644
--- a/agent_based/checkpoint_fw_ls.py
+++ b/agent_based/checkpoint_fw_ls.py
@@ -15,6 +15,7 @@
 # 2020-06-08: changed snmp-scan function
 # 2021-06-14: rewrite for cmk 2.0, added wato
 # 2021-08-09: fixed empty string_table, fixed log server default state
+# 2021-08-16: code cleanup
 #
 # sample snmpwalk
 #
@@ -102,20 +103,34 @@ class CheckPointFwLs(NamedTuple):
     fwLSConnSendRate: Optional[int]
 
 
+_fwLSConnState_des = {
+    0: 'Ok',
+    1: 'Error',
+    2: 'Not Active',
+}
+
+_fwLocalLoggingStat = {
+    0: 'Logging to log servers',
+    1: 'Logging local configured',
+    2: 'Logging local due to connectivity',
+    3: 'Logging local due to high rate',
+}
+
+
 def parse_checkpoint_fw_ls(string_table: List[StringTable]) -> Dict:
     if string_table != [[], []]:
         over_all, log_servers = string_table
 
-        fwlsconnoverall, fwlsconnoveralldesc, fwlocalloggingdesc, fwlocalloggingstat, fwLocalLoggingWriteRate, fwLoggingHandlingRate = \
-        over_all[0]
+        fwlsconnoverall, fwlsconnoveralldesc, fwlocalloggingdesc, fwlocalloggingstat, fwlocalloggingwriterate, \
+        fwlogginghandlingrate = over_all[0]
         parsed = {}
         parsed.update({'over all': CheckPointFwLsOverAll(
             fwlsconnoverall=int(fwlsconnoverall),
             fwlsconnoveralldesc=fwlsconnoveralldesc,
             fwlocalloggingdesc=fwlocalloggingdesc,
             fwlocalloggingstat=int(fwlocalloggingstat),
-            fwLocalLoggingWriteRate=int(fwLocalLoggingWriteRate) if fwLocalLoggingWriteRate.isdigit() else None,
-            fwLoggingHandlingRate=int(fwLoggingHandlingRate) if fwLoggingHandlingRate.isdigit() else None,
+            fwLocalLoggingWriteRate=int(fwlocalloggingwriterate) if fwlocalloggingwriterate.isdigit() else None,
+            fwLoggingHandlingRate=int(fwlogginghandlingrate) if fwlogginghandlingrate.isdigit() else None,
         )})
 
         for fwLSConnIndex, fwLSConnName, fwLSConnState, fwLSConnStateDesc, fwLSConnSendRate in log_servers:
@@ -136,24 +151,12 @@ def discovery_checkpoint_fw_ls(section: Dict) -> DiscoveryResult:
 
 
 def check_checkpoint_fw_ls(item, params, section: Dict) -> CheckResult:
-    fwLSConnState_des = {
-        0: 'Ok',
-        1: 'Error',
-        2: 'Not Active',
-    }
-
-    fwLocalLoggingStat = {
-        0: 'Logging to log servers',
-        1: 'Logging local configured',
-        2: 'Logging local due to connectivity',
-        3: 'Logging local due to high rate',
-    }
-
-    over_all = section['over all']
-
     if item == 'over all':
-        if over_all.fwLocalLoggingWriteRate is not None and over_all.fwLoggingHandlingRate is not None:  # R80.10 and up
+        over_all = section['over all']
+
+        if over_all.fwLocalLoggingWriteRate is not None:  # R80.10 and up
             yield Metric(name='checkpoint_fw_ls_localloggingwriterate', value=over_all.fwLocalLoggingWriteRate)
+        if over_all.fwLoggingHandlingRate is not None:
             yield Metric(name='checkpoint_fw_ls_logginghandlingrate', value=over_all.fwLoggingHandlingRate)
 
         yield Result(state=State(over_all.fwlsconnoverall), summary=over_all.fwlsconnoveralldesc)
@@ -163,13 +166,14 @@ def check_checkpoint_fw_ls(item, params, section: Dict) -> CheckResult:
             elif over_all.fwlocalloggingstat == 2:
                 yield Result(state=State.CRIT, summary=over_all.fwlocalloggingdesc)
             else:
-                yield Result(state=State.OK, summary=over_all.fwlocalloggingdesc)
+                yield Result(state=State.OK, notice=over_all.fwlocalloggingdesc)
     else:
         try:
             log_server = section[item]
         except IndexError:
             return
 
+        print(params)
         if log_server.fwLSConnSendRate is not None:  # R80.10 and up
             yield Metric(name='checkpoint_fw_ls_lsconnsendrate', value=log_server.fwLSConnSendRate)
 
@@ -178,11 +182,8 @@ def check_checkpoint_fw_ls(item, params, section: Dict) -> CheckResult:
         else:
             yield Result(state=State.OK, summary=f'State: {log_server.fwLSConnStateDesc}')
 
-        exp_connection_state = params.get('exp_connection_status', 'Log-Server Connected')
-        mon_connection_state = params.get('mon_connection_state', 1)
-
-        print(type(log_server.fwLSConnStateDesc))
-        print(exp_connection_state)
+        exp_connection_state = params['exp_connection_status']
+        mon_connection_state = params['mon_connection_state']
 
         if log_server.fwLSConnStateDesc.lower() != exp_connection_state.lower():
             yield Result(state=State(mon_connection_state),
@@ -230,6 +231,9 @@ register.check_plugin(
     service_name='FW Log server %s',
     discovery_function=discovery_checkpoint_fw_ls,
     check_function=check_checkpoint_fw_ls,
-    check_default_parameters={},
+    check_default_parameters={
+        'exp_connection_status': 'Log-Server Connected',
+        'mon_connection_state': 1,
+    },
     check_ruleset_name='checkpoint_fw_ls',
 )
diff --git a/agent_based/checkpoint_fwm_ls.py b/agent_based/checkpoint_fwm_ls.py
index ca05125..52d12ee 100644
--- a/agent_based/checkpoint_fwm_ls.py
+++ b/agent_based/checkpoint_fwm_ls.py
@@ -16,6 +16,7 @@
 # 2020-06-08: changed snmp-scan function
 # 2021-06-14: rewrite for cmk 2.0
 # 2021-08-09: fixed empty string_table
+# 2021-08-16: code cleanup
 #
 
 #
@@ -165,7 +166,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import (
 
 
 class CheckPointFwmR77(NamedTuple):
-    lsprodname: int
     lsvermajor: str
     lsverminor: str
     lsbuildnumber: int
@@ -176,10 +176,6 @@ class CheckPointFwmR77(NamedTuple):
 
 
 class CheckPointFwmR80(NamedTuple):
-    TotalReadLogs: int
-    TotalUpdatesAndLogsIndexed: int
-    TotalReadLogsErrors: int
-    TotalUpdatesAndLogsIndexedErrors: int
     UpdatesAndLogsIndexedRate: int
     ReadLogsRate: int
     UpdatesAndLogsIndexedRatePeak: int
@@ -188,80 +184,78 @@ class CheckPointFwmR80(NamedTuple):
 
 class CheckPointFwm(NamedTuple):
     R77: CheckPointFwmR77
-    R80: Optional[CheckPointFwmR80]
+    R80: Optional[CheckPointFwmR80] = None
 
 
-def parse_checkpoint_fwm_ls(string_table: List[StringTable]) -> CheckPointFwm:
-    if string_table != [[], []]:
-        r77, r80_indexer = string_table
-        lsprodname, lsvermajor, lsverminor, lsbuildnumber, lsfwmisalive, lsstatcode, lsstatshortdescr, lsstatlongdescr = \
-            r77[0]
+def parse_checkpoint_fwm_ls(string_table: List[StringTable]) -> Optional[CheckPointFwm]:
+    try:
+        lsvermajor, lsverminor, lsbuildnumber, lsfwmisalive, lsstatcode, lsstatshortdescr, \
+        lsstatlongdescr = string_table[0][0]
+    except IndexError:
+        return
+    except ValueError:
+        return
 
-        checkpointfwmr77 = CheckPointFwmR77(
-            lsprodname=lsprodname,
-            lsvermajor=lsvermajor,
-            lsverminor=lsverminor,
-            lsbuildnumber=lsbuildnumber,
-            lsfwmisalive=int(lsfwmisalive),
-            lsstatcode=int(lsstatcode),
-            lsstatshortdescr=lsstatshortdescr,
-            lsstatlongdescr=lsstatlongdescr,
-        )
-
-        checkpointfwmr80 = None
-
-        try:
-            r80_indexer = r80_indexer[0]
-        except IndexError:
-            return CheckPointFwm(
-                R77=checkpointfwmr77,
-                R80=checkpointfwmr80,
-            )
-
-        if len(r80_indexer) == 8:
-            TotalReadLogs, TotalUpdatesAndLogsIndexed, TotalReadLogsErrors, TotalUpdatesAndLogsIndexedErrors, \
-            UpdatesAndLogsIndexedRate, ReadLogsRate, UpdatesAndLogsIndexedRatePeak, ReadLogsRatePeak = r80_indexer
-
-            checkpointfwmr80 = CheckPointFwmR80(
-                TotalReadLogs=int(TotalReadLogs),
-                TotalUpdatesAndLogsIndexed=int(TotalUpdatesAndLogsIndexed),
-                TotalReadLogsErrors=int(TotalReadLogsErrors),
-                TotalUpdatesAndLogsIndexedErrors=int(TotalUpdatesAndLogsIndexedErrors),
-                UpdatesAndLogsIndexedRate=int(UpdatesAndLogsIndexedRate),
-                ReadLogsRate=int(ReadLogsRate),
-                UpdatesAndLogsIndexedRatePeak=int(UpdatesAndLogsIndexedRatePeak),
-                ReadLogsRatePeak=int(ReadLogsRatePeak),
-            )
+    checkpointfwmr77 = CheckPointFwmR77(
+        lsvermajor=lsvermajor,
+        lsverminor=lsverminor,
+        lsbuildnumber=lsbuildnumber,
+        lsfwmisalive=int(lsfwmisalive),
+        lsstatcode=int(lsstatcode),
+        lsstatshortdescr=lsstatshortdescr,
+        lsstatlongdescr=lsstatlongdescr,
+    )
 
+    try:
+        UpdatesAndLogsIndexedRate, ReadLogsRate, UpdatesAndLogsIndexedRatePeak, ReadLogsRatePeak = string_table[1][0]
+    except IndexError:
         return CheckPointFwm(
             R77=checkpointfwmr77,
-            R80=checkpointfwmr80,
+            R80=None,
+        )
+    except ValueError:
+        return CheckPointFwm(
+            R77=checkpointfwmr77,
+            R80=None,
         )
 
+    checkpointfwmr80 = CheckPointFwmR80(
+        UpdatesAndLogsIndexedRate=int(UpdatesAndLogsIndexedRate),
+        ReadLogsRate=int(ReadLogsRate),
+        UpdatesAndLogsIndexedRatePeak=int(UpdatesAndLogsIndexedRatePeak),
+        ReadLogsRatePeak=int(ReadLogsRatePeak),
+    )
+
+    return CheckPointFwm(
+        R77=checkpointfwmr77,
+        R80=checkpointfwmr80,
+    )
+
 
 def discovery_checkpoint_fwm_ls(section: CheckPointFwm) -> DiscoveryResult:
     yield Service()
 
 
 def check_checkpoint_fwm_ls(params, section: CheckPointFwm) -> CheckResult:
-    yield Result(state=State.OK,
-                 summary=f'{section.R77.lsprodname}, version: {section.R77.lsvermajor}.{section.R77.lsverminor}, Build: {section.R77.lsbuildnumber}')
+    yield Result(state=State.OK, summary=f'Version: {section.R77.lsvermajor}.{section.R77.lsverminor}')
+    yield Result(state=State.OK, summary=f'Build: {section.R77.lsbuildnumber}')
 
-    if not params.get('ignore_status_on_r80_10'):
+    if not params['ignore_status_on_r80_10']:
         if section.R77.lsfwmisalive != 1:
             yield Result(state=State.CRIT, summary='Is not alive')
         if section.R77.lsstatcode != 0:
             yield Result(state=State.CRIT,
-                         summary=f'Status: {section.R77.lsstatshortdescr}, {section.R77.lsstatlongdescr}')
+                         summary=f'Status: {section.R77.lsstatshortdescr}',
+                         details=f'Status: {section.R77.lsstatlongdescr}')
     if section.R80 is not None:
-        yield Metric(name='checkpoint_fwm_ls_totalreadlogs', value=section.R80.TotalReadLogs)
-        yield Metric(name='checkpoint_fwm_ls_totalupdatesandlogsindexed', value=section.R80.TotalUpdatesAndLogsIndexed)
-        yield Metric(name='checkpoint_fwm_ls_totalreadlogserrors', value=section.R80.TotalReadLogsErrors)
-        yield Metric(name='checkpoint_fwm_ls_totalupdatesandlogsindexederrors', value=section.R80.TotalUpdatesAndLogsIndexedErrors)
-        yield Metric(name='checkpoint_fwm_ls_updatesandlogsindexedrate', value=section.R80.UpdatesAndLogsIndexedRate)
-        yield Metric(name='checkpoint_fwm_ls_updatesandlogsindexedratepeak', value=section.R80.UpdatesAndLogsIndexedRatePeak)
-        yield Metric(name='checkpoint_fwm_ls_readlogsrate', value=section.R80.ReadLogsRate)
-        yield Metric(name='checkpoint_fwm_ls_readlogsratepeak', value=section.R80.ReadLogsRatePeak)
+        for key, value in [
+            ('checkpoint_fwm_ls_updatesandlogsindexedrate', section.R80.UpdatesAndLogsIndexedRate),
+            ('checkpoint_fwm_ls_updatesandlogsindexedratepeak', section.R80.UpdatesAndLogsIndexedRatePeak),
+            ('checkpoint_fwm_ls_readlogsrate', section.R80.ReadLogsRate),
+            ('checkpoint_fwm_ls_readlogsratepeak', section.R80.ReadLogsRatePeak),
+        ]:
+            if value is not None:
+                yield Metric(name=key, value=value)
 
 
 register.snmp_section(
@@ -271,7 +265,6 @@ register.snmp_section(
         SNMPTree(
             base='.1.3.6.1.4.1.2620.1.11',  # CHECKPOINT-MIB::ls
             oids=[
-                '1',  # lsProdName
                 '2',  # lsVerMajor
                 '3',  # lsVerMinor
                 '4',  # lsBuildNumber
@@ -284,19 +277,10 @@ register.snmp_section(
         SNMPTree(
             base='.1.3.6.1.4.1.2620.1.11.14.5',  # CHECKPOINT-MIB::lsIndexerInfo
             oids=[
-                '1',  # lsIndexerInfoTotalReadLogs
-                '2',  # lsIndexerInfoTotalUpdatesAndLogsIndexed
-                '3',  # lsIndexerInfoTotalReadLogsErrors
-                '4',  # lsIndexerInfoTotalUpdatesAndLogsIndexedErrors
                 '5',  # lsIndexerInfoUpdatesAndLogsIndexedRate
                 '6',  # lsIndexerInfoReadLogsRate
                 '7',  # lsIndexerInfoUpdatesAndLogsIndexedRatePeak
                 '8',  # lsIndexerInfoReadLogsRatePeak
-                # '9',   # lsIndexerInfo_9
-                # '10',  # lsIndexerInfo_10
-                # '11',  # lsIndexerInfo_11
-                # '12',  # lsIndexerInfo_12
-                # '13',  # lsIndexerInfo_13
             ]
         )
 
@@ -318,62 +302,3 @@ register.check_plugin(
     check_default_parameters={'ignore_status_on_r80_10': False, },
     check_ruleset_name='checkpoint_fwm_ls',
 )
-
-# ('.1.3.6.1.4.1.2620.1.11.14', [  # CHECKPOINT-MIB::lsLoggingInfo
-#     '1',  # lsLogReceiveRate
-#     '2',  # lsLogReceiveRatePeak
-#     '3',  # lsLogReceiveRate10Min
-#     '6',  # lsLogReceiveRate1Hour
-# ]),
-
-# OMD[build]:~$ snmpwalk -v2c -c komsa/alf-r81 -ObentU simulant .1.3.6.1.4.1.2620.1.11.14.4.1
-# .1.3.6.1.4.1.2620.1.11.14.4.1.1.1.0 = Gauge32: 1
-# .1.3.6.1.4.1.2620.1.11.14.4.1.1.2.0 = Gauge32: 2
-# .1.3.6.1.4.1.2620.1.11.14.4.1.1.3.0 = Gauge32: 3
-# .1.3.6.1.4.1.2620.1.11.14.4.1.1.4.0 = Gauge32: 4
-# .1.3.6.1.4.1.2620.1.11.14.4.1.1.5.0 = Gauge32: 5
-# .1.3.6.1.4.1.2620.1.11.14.4.1.1.6.0 = Gauge32: 6
-# .1.3.6.1.4.1.2620.1.11.14.4.1.1.7.0 = Gauge32: 7
-# .1.3.6.1.4.1.2620.1.11.14.4.1.2.1.0 = STRING: "Local Clients"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.2.2.0 = STRING: "bill01"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.2.3.0 = STRING: "bill02"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.2.4.0 = STRING: "donald01"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.2.5.0 = STRING: "donald02"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.2.6.0 = STRING: "charlie02"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.2.7.0 = STRING: "charlie01"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.3.1.0 = STRING: "Connected"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.3.2.0 = STRING: "Connected"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.3.3.0 = STRING: "Connected"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.3.4.0 = STRING: "Connected"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.3.5.0 = STRING: "Connected"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.3.6.0 = STRING: "Connected"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.3.7.0 = STRING: "Connected"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.4.1.0 = STRING: "N/A"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.4.2.0 = STRING: "Tue Feb  9 13:51:34 2021"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.4.3.0 = STRING: "Tue Feb  9 13:51:34 2021"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.4.4.0 = STRING: "Tue Feb  9 13:51:34 2021"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.4.5.0 = STRING: "Tue Feb  9 13:51:34 2021"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.4.6.0 = STRING: "Tue Feb  9 13:51:34 2021"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.4.7.0 = STRING: "Tue Feb  9 13:51:34 2021"
-# .1.3.6.1.4.1.2620.1.11.14.4.1.5.1.0 = Gauge32: 0
-# .1.3.6.1.4.1.2620.1.11.14.4.1.5.2.0 = Gauge32: 0
-# .1.3.6.1.4.1.2620.1.11.14.4.1.5.3.0 = Gauge32: 837
-# .1.3.6.1.4.1.2620.1.11.14.4.1.5.4.0 = Gauge32: 0
-# .1.3.6.1.4.1.2620.1.11.14.4.1.5.5.0 = Gauge32: 1
-# .1.3.6.1.4.1.2620.1.11.14.4.1.5.6.0 = Gauge32: 0
-# .1.3.6.1.4.1.2620.1.11.14.4.1.5.7.0 = Gauge32: 5
-
-# ('.1.3.6.1.4.1.2620.1.11.14.4.1', [  # CHECKPOINT-MIB::lsConnectedGatewaysEntry
-#     '1',  # lsGWIndex
-#     '2',  # lsGWIP
-#     '3',  # lsGWState
-#     '4',  # lsGWLastLoginTime
-#     '5',  # lsGWLogReceiveRate
-#      ]),
-# ('.1.3.6.1.4.1.2620.1.11.14.7.1', [  # CHECKPOINT-MIB::lsConnectedClientsEntry
-#     '1',   # lsIndex
-#     '2',   # lsClientName
-#     '3',   # lsClientHost
-#     '4',   # lsClientDbLock
-#     '5',   # lsClientDbLock
-#     ]),
diff --git a/checkpoint_log_server.mkp b/checkpoint_log_server.mkp
index d496444e1c3cb55966faa2f2542dafe047bf0c61..b9dd3bfa9e7b0b1413991f8bf8299a7df5334faa 100644
GIT binary patch
delta 6608
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
OcJP0IlSfVf7y$ruYAe40

literal 7201
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

diff --git a/packages/checkpoint_log_server b/packages/checkpoint_log_server
index 9d3446e..423b834 100644
--- a/packages/checkpoint_log_server
+++ b/packages/checkpoint_log_server
@@ -11,7 +11,7 @@
  'name': 'checkpoint_log_server',
  'num_files': 7,
  'title': 'Check Point Log service status',
- 'version': '20210809.v0.2a',
+ 'version': '20210816.v0.2b',
  'version.min_required': '2.0.0',
  'version.packaged': '2021.07.14',
  'version.usable_until': None}
\ No newline at end of file
diff --git a/web/plugins/metrics/checkpoint_fw_log.py b/web/plugins/metrics/checkpoint_fw_log.py
index 90bf34c..9a3fc21 100644
--- a/web/plugins/metrics/checkpoint_fw_log.py
+++ b/web/plugins/metrics/checkpoint_fw_log.py
@@ -40,27 +40,6 @@ metric_info['checkpoint_fw_ls_lsconnsendrate'] = {
     'color': '31/a',
 }
 
-metric_info['checkpoint_fwm_ls_totalreadlogs'] = {
-    'title': _('Total read logs'),
-    'unit': '1/s',
-    'color': '11/a',
-}
-metric_info['checkpoint_fwm_ls_totalupdatesandlogsindexed'] = {
-    'title': _('Total updates and logs indexed'),
-    'unit': 'count',
-    'color': '21/a',
-}
-metric_info['checkpoint_fwm_ls_totalreadlogserrors'] = {
-    'title': _('Total read log errors'),
-    'unit': '1/s',
-    'color': '31/a',
-}
-metric_info['checkpoint_fwm_ls_totalupdatesandlogsindexederrors'] = {
-    'title': _('Total updates and logs indexed errors'),
-    'unit': 'count',
-    'color': '41/a',
-}
-
 metric_info['checkpoint_fwm_ls_updatesandlogsindexedrate'] = {
     'title': _('Updates and logs index rate'),
     'unit': '1/s',
@@ -75,7 +54,7 @@ metric_info['checkpoint_fwm_ls_updatesandlogsindexedratepeak'] = {
 metric_info['checkpoint_fwm_ls_readlogsrate'] = {
     'title': _('Logs read rate'),
     'unit': '1/s',
-    'color': '12/a',
+    'color': '26/a',
 }
 metric_info['checkpoint_fwm_ls_readlogsratepeak'] = {
     'title': _('Logs read peak rate'),
@@ -95,6 +74,11 @@ graph_info['checkpoint_fw_ls_over_all'] = {
         ('checkpoint_fw_ls_localloggingwriterate', 'line'),
         ('checkpoint_fw_ls_logginghandlingrate', 'line'),
     ],
+    'optional_metrics': [
+        'checkpoint_fw_ls_localloggingwriterate',
+        'checkpoint_fw_ls_logginghandlingrate'
+    ],
+    'range': (0, 'checkpoint_fw_ls_logginghandlingrate:max'),
 }
 
 graph_info['checkpoint_fw_ls_gateway'] = {
@@ -102,30 +86,33 @@ graph_info['checkpoint_fw_ls_gateway'] = {
     'metrics': [
         ('checkpoint_fw_ls_lsconnsendrate', 'line'),
     ],
+    'range': (0, 'checkpoint_fw_ls_lsconnsendrate:max'),
 }
 
-graph_info['checkpoint_fwm_ls_management'] = {
-    'title': _('Check Point Management Firewall Log server'),
+graph_info['checkpoint_fwm_ls_management_read'] = {
+    'title': _('Check Point Management Firewall Log server read rate'),
     'metrics': [
-        ('checkpoint_fwm_ls_updatesandlogsindexedratepeak', 'line'),
-        ('checkpoint_fwm_ls_updatesandlogsindexedrate', 'line'),
+        ('checkpoint_fwm_ls_readlogsratepeak', 'line'),
+        ('checkpoint_fwm_ls_readlogsrate', 'line'),
     ],
-}
-
-graph_info['checkpoint_fwm_ls_read_logs'] = {
-    'title': _('Check Point Management Firewall Log server read logs'),
-    'metrics': [
-        ('checkpoint_fwm_ls_totalreadlogserrors', 'line'),
-        ('checkpoint_fwm_ls_totalreadlogs', 'line'),
+    'optional_metrics': [
+        'checkpoint_fwm_ls_readlogsratepeak',
+        'checkpoint_fwm_ls_readlogsrate',
     ],
+    'range': (0, 'checkpoint_fwm_ls_readlogsrate:max'),
 }
 
-graph_info['checkpoint_fwm_ls_updates'] = {
-    'title': _('Check Point Management Firewall Log server updates and logs indexed'),
+graph_info['checkpoint_fwm_ls_management_indexed'] = {
+    'title': _('Check Point Management Firewall Log server index rate'),
     'metrics': [
-        ('checkpoint_fwm_ls_totalupdatesandlogsindexederrors', 'line'),
-        ('checkpoint_fwm_ls_totalupdatesandlogsindexed', 'line'),
+        ('checkpoint_fwm_ls_updatesandlogsindexedratepeak', 'line'),
+        ('checkpoint_fwm_ls_updatesandlogsindexedrate', 'line'),
     ],
+    'optional_metrics': [
+        'checkpoint_fwm_ls_updatesandlogsindexedratepeak',
+        'checkpoint_fwm_ls_updatesandlogsindexedrate',
+    ],
+    'range': (0, 'checkpoint_fwm_ls_updatesandlogsindexedrate:max'),
 }
 
 ##############################################################################
@@ -154,4 +141,19 @@ perfometer_info.append({
     'metric': 'checkpoint_fw_ls_lsconnsendrate',
     'half_value': 500.0,
     'exponent': 2,
-})
\ No newline at end of file
+})
+
+perfometer_info.append(('stacked', [
+    {
+        'type': 'logarithmic',
+        'metric': 'checkpoint_fwm_ls_readlogsrate',
+        'half_value': 1000.0,
+        'exponent': 2,
+    },
+    {
+        'type': 'logarithmic',
+        'metric': 'checkpoint_fwm_ls_updatesandlogsindexedrate',
+        'half_value': 1000.0,
+        'exponent': 2,
+    },
+]))
diff --git a/web/plugins/wato/checkpoint_fw_ls.py b/web/plugins/wato/checkpoint_fw_ls.py
index 8880d5e..765f189 100644
--- a/web/plugins/wato/checkpoint_fw_ls.py
+++ b/web/plugins/wato/checkpoint_fw_ls.py
@@ -46,7 +46,7 @@ rulespec_registry.register(
     CheckParameterRulespecWithItem(
         check_group_name='checkpoint_fw_ls',
         group=RulespecGroupCheckParametersNetworking,
-        item_spec=lambda: TextAscii(title=_('Check Point Firewall gateway log server'), ),
+        item_spec=lambda: TextAscii(title=_('Log server IP'), ),
         match_type='dict',
         parameter_valuespec=_parameter_valuespec_checkpoint_fw_ls,
         title=lambda: _('Check Point Firewall gateway log server'),
-- 
GitLab