pytbox 0.1.6__tar.gz → 0.1.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pytbox might be problematic. Click here for more details.

Files changed (85) hide show
  1. {pytbox-0.1.6/src/pytbox.egg-info → pytbox-0.1.8}/PKG-INFO +1 -1
  2. {pytbox-0.1.6 → pytbox-0.1.8}/pyproject.toml +1 -1
  3. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/alert/ping.py +0 -1
  4. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/base.py +6 -1
  5. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/database/victoriametrics.py +103 -7
  6. pytbox-0.1.8/src/pytbox/utils/cronjob.py +79 -0
  7. {pytbox-0.1.6 → pytbox-0.1.8/src/pytbox.egg-info}/PKG-INFO +1 -1
  8. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox.egg-info/SOURCES.txt +1 -1
  9. {pytbox-0.1.6 → pytbox-0.1.8}/tests/test_victoriametrics.py +3 -2
  10. pytbox-0.1.6/src/pytbox/utils/ping_checker.py +0 -1
  11. {pytbox-0.1.6 → pytbox-0.1.8}/MANIFEST.in +0 -0
  12. {pytbox-0.1.6 → pytbox-0.1.8}/README.md +0 -0
  13. {pytbox-0.1.6 → pytbox-0.1.8}/setup.cfg +0 -0
  14. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/alert/alert_handler.py +0 -0
  15. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/alicloud/sls.py +0 -0
  16. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/build_config.py +0 -0
  17. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/instances.toml +0 -0
  18. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/__init__.py +0 -0
  19. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.cpu/cpu.toml.j2 +0 -0
  20. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.disk/disk.toml.j2 +0 -0
  21. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.diskio/diskio.toml.j2 +0 -0
  22. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.dns_query/dns_query.toml.j2 +0 -0
  23. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.http_response/http_response.toml.j2 +0 -0
  24. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.mem/mem.toml.j2 +0 -0
  25. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.net/net.toml.j2 +0 -0
  26. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.net_response/net_response.toml.j2 +0 -0
  27. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.ping/ping.toml.j2 +0 -0
  28. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.prometheus/prometheus.toml.j2 +0 -0
  29. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.snmp/cisco_interface.toml.j2 +0 -0
  30. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.snmp/cisco_system.toml.j2 +0 -0
  31. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.snmp/h3c_interface.toml.j2 +0 -0
  32. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.snmp/h3c_system.toml.j2 +0 -0
  33. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.snmp/huawei_interface.toml.j2 +0 -0
  34. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.snmp/huawei_system.toml.j2 +0 -0
  35. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.snmp/ruijie_interface.toml.j2 +0 -0
  36. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.snmp/ruijie_system.toml.j2 +0 -0
  37. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/categraf/jinja2/input.vsphere/vsphere.toml.j2 +0 -0
  38. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/__init__.py +0 -0
  39. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/categraf/__init__.py +0 -0
  40. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/categraf/commands.py +0 -0
  41. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/commands/vm.py +0 -0
  42. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/common/__init__.py +0 -0
  43. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/common/options.py +0 -0
  44. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/common/utils.py +0 -0
  45. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/formatters/__init__.py +0 -0
  46. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/formatters/output.py +0 -0
  47. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli/main.py +0 -0
  48. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/cli.py +0 -0
  49. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/common/__init__.py +0 -0
  50. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/database/mongo.py +0 -0
  51. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/dida365.py +0 -0
  52. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/excel.py +0 -0
  53. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/feishu/client.py +0 -0
  54. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/feishu/endpoints.py +0 -0
  55. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/feishu/errors.py +0 -0
  56. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/feishu/helpers.py +0 -0
  57. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/feishu/typing.py +0 -0
  58. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/log/logger.py +0 -0
  59. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/log/victorialog.py +0 -0
  60. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/mail/alimail.py +0 -0
  61. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/mail/client.py +0 -0
  62. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/mail/mail_detail.py +0 -0
  63. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/network/meraki.py +0 -0
  64. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/onepassword_connect.py +0 -0
  65. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/onepassword_sa.py +0 -0
  66. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/pyjira.py +0 -0
  67. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/utils/env.py +0 -0
  68. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/utils/load_config.py +0 -0
  69. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/utils/load_vm_devfile.py +0 -0
  70. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/utils/response.py +0 -0
  71. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/utils/richutils.py +0 -0
  72. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/utils/timeutils.py +0 -0
  73. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/vmware.py +0 -0
  74. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox/win/ad.py +0 -0
  75. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox.egg-info/dependency_links.txt +0 -0
  76. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox.egg-info/entry_points.txt +0 -0
  77. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox.egg-info/requires.txt +0 -0
  78. {pytbox-0.1.6 → pytbox-0.1.8}/src/pytbox.egg-info/top_level.txt +0 -0
  79. {pytbox-0.1.6 → pytbox-0.1.8}/tests/test_base.py +0 -0
  80. {pytbox-0.1.6 → pytbox-0.1.8}/tests/test_feishu.py +0 -0
  81. {pytbox-0.1.6 → pytbox-0.1.8}/tests/test_load_jsonfile.py +0 -0
  82. {pytbox-0.1.6 → pytbox-0.1.8}/tests/test_logger.py +0 -0
  83. {pytbox-0.1.6 → pytbox-0.1.8}/tests/test_onepassword_connect.py +0 -0
  84. {pytbox-0.1.6 → pytbox-0.1.8}/tests/test_onepassword_sa.py +0 -0
  85. {pytbox-0.1.6 → pytbox-0.1.8}/tests/test_vmware.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytbox
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: A collection of Python integrations and utilities (Feishu, Dida365, VictoriaMetrics, ...)
5
5
  Author-email: mingming hou <houm01@foxmail.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pytbox"
7
- version = "0.1.6"
7
+ version = "0.1.8"
8
8
  description = "A collection of Python integrations and utilities (Feishu, Dida365, VictoriaMetrics, ...)"
9
9
  authors = [{ name = "mingming hou", email = "houm01@foxmail.com" }]
10
10
  license = "MIT"
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
-
4
3
  from ..database.victoriametrics import VictoriaMetrics
5
4
  from ..lib.load_config import load_config
6
5
 
@@ -16,6 +16,7 @@ from pytbox.pyjira import PyJira
16
16
  from pytbox.mail.client import MailClient
17
17
  from pytbox.mail.alimail import AliMail
18
18
  from pytbox.alicloud.sls import AliCloudSls
19
+ from pytbox.utils.cronjob import cronjob_counter
19
20
 
20
21
 
21
22
  config = load_config_by_file(path='/workspaces/pytbox/tests/alert/config_dev.toml', oc_vault_id=os.environ.get('oc_vault_id'))
@@ -107,4 +108,8 @@ sls = AliCloudSls(
107
108
  access_key_secret=config['alicloud']['account1']['access_key_secret'],
108
109
  project=config['alicloud']['account1']['project'],
109
110
  logstore=config['alicloud']['account1']['logstore']
110
- )
111
+ )
112
+
113
+
114
+ def get_cronjob_counter(app_type='', app='', comment=None, schedule_interval=None, schedule_cron=None):
115
+ return cronjob_counter(vm=vm, log=get_logger('cronjob_counter'), app_type=app_type, app=app, comment=comment, schedule_interval=schedule_interval, schedule_cron=schedule_cron)
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
+ import time
3
4
  import json
4
- from typing import Literal, Optional
5
+ from typing import Literal, Optional, Dict, List
5
6
  import requests
6
7
  from ..utils.response import ReturnResponse
7
8
  from ..utils.load_vm_devfile import load_dev_file
@@ -9,7 +10,7 @@ from ..utils.load_vm_devfile import load_dev_file
9
10
 
10
11
  class VictoriaMetrics:
11
12
 
12
- def __init__(self, url: str='', timeout: int=3) -> None:
13
+ def __init__(self, url: str='', timeout: int=3, env: str='prod') -> None:
13
14
  self.url = url
14
15
  self.timeout = timeout
15
16
  self.session = requests.Session()
@@ -17,7 +18,44 @@ class VictoriaMetrics:
17
18
  'Content-Type': 'application/json',
18
19
  'Accept': 'application/json'
19
20
  })
21
+ self.env = env
22
+
23
+ def insert(self, metric_name: str = '', labels: Dict[str, str] = None,
24
+ value: List[float] = None, timestamp: int = None) -> ReturnResponse:
25
+ """插入指标数据。
26
+
27
+ Args:
28
+ metric_name: 指标名称
29
+ labels: 标签字典
30
+ value: 值列表
31
+ timestamp: 时间戳(毫秒),默认为当前时间
32
+
33
+ Raises:
34
+ requests.RequestException: 当请求失败时抛出
35
+ """
36
+ if labels is None:
37
+ labels = {}
38
+ if value is None:
39
+ value = 1
40
+ if timestamp is None:
41
+ timestamp = int(time.time() * 1000)
42
+
43
+ url = f"{self.url}/api/v1/import"
44
+ data = {
45
+ "metric": {
46
+ "__name__": metric_name,
47
+ **labels
48
+ },
49
+ "values": [value],
50
+ "timestamps": [timestamp]
51
+ }
20
52
 
53
+ try:
54
+ response = requests.post(url, json=data, timeout=self.timeout)
55
+ return ReturnResponse(code=0, msg=f"数据插入成功,状态码: {response.status_code}, metric_name: {metric_name}, labels: {labels}, value: {value}, timestamp: {timestamp}")
56
+ except requests.RequestException as e:
57
+ return ReturnResponse(code=1, msg=f"数据插入失败: {e}")
58
+
21
59
  def query(self, query: str=None, output_format: Literal['json']=None) -> ReturnResponse:
22
60
  '''
23
61
  查询指标数据
@@ -208,9 +246,67 @@ class VictoriaMetrics:
208
246
  '''
209
247
  q = f"""avg_over_time(snmp_interface_ifOperStatus{{sysName="{sysname}", ifName="{if_name}"}}[{last_minute}m])"""
210
248
  r = self.query(query=q)
211
- status_code = r.data[0]['value'][1]
212
- if status_code == 1:
213
- status = 'up'
249
+ if r.code == 0:
250
+ status_code = int(r.data[0]['value'][1])
251
+ if status_code == 1:
252
+ status = 'up'
253
+ else:
254
+ status = 'down'
255
+ return ReturnResponse(code=0, msg=f"{sysname} {if_name} 最近 {last_minute} 分钟端口状态为 {status}", data=status)
214
256
  else:
215
- status = 'down'
216
- return ReturnResponse(code=0, msg=f"{sysname} {if_name} 最近 {last_minute} 分钟端口状态为 {status}", data=status)
257
+ return r
258
+
259
+ def insert_cronjob_run_status(self,
260
+ app_type: Literal['alert', 'meraki', 'other']='other',
261
+ app: str='',
262
+ status_code: Literal[0, 1]=1,
263
+ comment: str=None,
264
+ schedule_interval: str=None,
265
+ schedule_cron: str=None
266
+ ) -> ReturnResponse:
267
+ labels = {
268
+ "app": app,
269
+ "env": self.env,
270
+ }
271
+ if app_type:
272
+ labels['app_type'] = app_type
273
+ if comment:
274
+ labels['comment'] = comment
275
+
276
+ if schedule_interval:
277
+ labels['schedule_type'] = 'interval'
278
+ labels['schedule_interval'] = schedule_interval
279
+
280
+ if schedule_cron:
281
+ labels['schedule_type'] = 'cron'
282
+ labels['schedule_cron'] = schedule_cron
283
+
284
+ r = self.insert(metric_name="cronjob_run_status", labels=labels, value=status_code)
285
+ return r
286
+
287
+ def insert_cronjob_duration_seconds(self,
288
+ app_type: Literal['alert', 'meraki', 'other']='other',
289
+ app: str='',
290
+ duration_seconds: float=None,
291
+ comment: str=None,
292
+ schedule_interval: str=None,
293
+ schedule_cron: str=None
294
+ ) -> ReturnResponse:
295
+ labels = {
296
+ "app": app,
297
+ "env": self.env
298
+ }
299
+ if app_type:
300
+ labels['app_type'] = app_type
301
+ if comment:
302
+ labels['comment'] = comment
303
+
304
+ if schedule_interval:
305
+ labels['schedule_type'] = 'interval'
306
+ labels['schedule_interval'] = schedule_interval
307
+
308
+ if schedule_cron:
309
+ labels['schedule_type'] = 'cron'
310
+ labels['schedule_cron'] = schedule_cron
311
+ r = self.insert(metric_name="cronjob_run_duration_seconds", labels=labels, value=duration_seconds)
312
+ return r
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import time
4
+ from functools import wraps
5
+ from typing import Literal
6
+ from ..database.victoriametrics import VictoriaMetrics
7
+
8
+
9
+ def cronjob_counter(vm: VictoriaMetrics=None, log: str=None, app_type: Literal['']='', app='', comment=None, schedule_interval=None, schedule_cron=None):
10
+ """计算函数运行时间的装饰器,支持记录到 VictoriaMetrics
11
+
12
+ Args:
13
+ app_type: 应用类型 ('alert', 'meraki', 'other')
14
+ app: 应用名称
15
+ comment: 备注信息
16
+ schedule_interval: 定时任务间隔(如 '1m', '5m')
17
+ schedule_cron: cron 表达式(如 '0 */5 * * *')
18
+ """
19
+ def decorator(func):
20
+ @wraps(func)
21
+ def wrapper(*args, **kwargs):
22
+ start_time = time.time()
23
+
24
+ try:
25
+ result = func(*args, **kwargs)
26
+ end_time = time.time()
27
+ elapsed_time = end_time - start_time
28
+
29
+ # 记录任务成功完成状态
30
+ vm.insert_cronjob_run_status(
31
+ app_type=app_type,
32
+ app=app,
33
+ status_code=1, # 0 表示成功完成
34
+ comment=f"成功完成: {comment}" if comment else "任务成功完成",
35
+ schedule_interval=schedule_interval,
36
+ schedule_cron=schedule_cron
37
+ )
38
+
39
+ # 记录执行耗时
40
+ vm.insert_cronjob_duration_seconds(
41
+ app_type=app_type,
42
+ app=app,
43
+ duration_seconds=elapsed_time,
44
+ comment=comment,
45
+ schedule_interval=schedule_interval,
46
+ schedule_cron=schedule_cron
47
+ )
48
+ log.info(f"{app} 任务成功完成, 耗时 {elapsed_time:.2f} 秒")
49
+
50
+ return result
51
+
52
+ except Exception as e:
53
+ end_time = time.time()
54
+ elapsed_time = end_time - start_time
55
+
56
+ # 记录任务失败状态
57
+ error_comment = f"执行出错: {str(e)}" if not comment else f"{comment} (出错: {str(e)})"
58
+ vm.insert_cronjob_run_status(
59
+ app_type=app_type,
60
+ app=app,
61
+ status_code=0, # 1 表示失败
62
+ comment=error_comment,
63
+ schedule_interval=schedule_interval,
64
+ schedule_cron=schedule_cron
65
+ )
66
+
67
+ # 即使出错也记录耗时
68
+ vm.insert_cronjob_duration_seconds(
69
+ app_type=app_type,
70
+ app=app,
71
+ duration_seconds=elapsed_time,
72
+ comment=error_comment,
73
+ schedule_interval=schedule_interval,
74
+ schedule_cron=schedule_cron
75
+ )
76
+ log.error(f"任务失败: {error_comment}")
77
+ raise
78
+ return wrapper
79
+ return decorator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytbox
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: A collection of Python integrations and utilities (Feishu, Dida365, VictoriaMetrics, ...)
5
5
  Author-email: mingming hou <houm01@foxmail.com>
6
6
  License-Expression: MIT
@@ -64,10 +64,10 @@ src/pytbox/mail/alimail.py
64
64
  src/pytbox/mail/client.py
65
65
  src/pytbox/mail/mail_detail.py
66
66
  src/pytbox/network/meraki.py
67
+ src/pytbox/utils/cronjob.py
67
68
  src/pytbox/utils/env.py
68
69
  src/pytbox/utils/load_config.py
69
70
  src/pytbox/utils/load_vm_devfile.py
70
- src/pytbox/utils/ping_checker.py
71
71
  src/pytbox/utils/response.py
72
72
  src/pytbox/utils/richutils.py
73
73
  src/pytbox/utils/timeutils.py
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- from pytbox.base import vm
4
-
3
+ from pytbox.base import vm, get_cronjob_counter
4
+ from pytbox.utils.cronjob import cronjob_counter
5
5
 
6
6
 
7
7
  def test_query():
@@ -16,6 +16,7 @@ def test_get_labels():
16
16
  r = vm.get_labels('ping_average_response_ms')
17
17
  print(r)
18
18
 
19
+ @get_cronjob_counter(app_type="tests", app="tests.test_victoriameterics", schedule_interval='5s')
19
20
  def test_check_snmp_port_status():
20
21
  r = vm.check_snmp_port_status(sysname="shylf-prod-coresw-ce6820-182", if_name="10GE1/0/47", last_minute=10)
21
22
  print(r)
@@ -1 +0,0 @@
1
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes