添加python客户端支持

This commit is contained in:
gotoeasy
2024-03-30 22:49:03 +08:00
parent abfbf47d2b
commit 9990d3527b
8 changed files with 318 additions and 0 deletions

4
.gitignore vendored
View File

@@ -27,3 +27,7 @@
/glc/www/web/src/pkgs/*/
/glc/www/web/src/pkgs/index-pkgs.js
/glc-python-client/build/
/glc-python-client/dist/
/glc-python-client/glogcenter.egg-info/

21
glc-python-client/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 gotoeasy.top
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1 @@
include README.md LICENSE

View File

@@ -0,0 +1 @@
日志中心的 python 客户端

View File

@@ -0,0 +1,3 @@
from .glc import debug, info, warn, error, GlcData
__all__ = ['debug', 'info', 'warn', 'error', 'GlcData']

View File

@@ -0,0 +1,8 @@
# 8b d8 Yb dP 88""Yb db dP""b8 88 dP db dP""b8 888888
# 88b d88 YbdP 88__dP dPYb dP `" 88odP dPYb dP `" 88__
# 88YbdP88 8P 88""" dP__Yb Yb 88"Yb dP__Yb Yb "88 88""
# 88 YY 88 dP 88 dP""""Yb YboodP 88 Yb dP""""Yb YboodP 888888
VERSION = (5, 2, 0)
__version__ = '.'.join(map(str, VERSION))

View File

@@ -0,0 +1,149 @@
import os
import json
import datetime
import requests
import platform
import socket
import netifaces
from decimal import Decimal
import random
import sys
cached_ip = None
server_name = None
def get_server_name():
global server_name
if server_name is None:
server_name = platform.node()
return server_name
def get_intranet_ip():
global cached_ip
if cached_ip is None:
interfaces = netifaces.interfaces()
ip_addresses = []
for interface in interfaces:
addresses = netifaces.ifaddresses(interface).get(socket.AF_INET)
if addresses:
for address in addresses:
ip = address['addr']
if ip.startswith('192.') or ip.startswith('172.') or ip.startswith('10.'):
ip_addresses.append(ip)
# 对IP地址列表按照特定优先级排序(192优先)
sorted_ips = sorted(ip_addresses, key=lambda x: (x.startswith('192.'), x.startswith('172.'), x.startswith('10.')))
if sorted_ips:
cached_ip = sorted_ips[0]
else:
cached_ip = '127.0.0.1'
return cached_ip
def hash_string(input_str = ''):
rs = 53653
i = len(input_str) if input_str is not None else 0
while i > 0:
rs = (rs * 33) ^ ord(input_str[i - 1])
i -= 1
return str(Decimal(rs & 0xFFFFFFFF).to_eng_string())
# yyyy-MM-dd HH:mm:ss.SSS
def get_current_time():
current_time = datetime.datetime.now()
return current_time.strftime('%Y-%m-%d %H:%M:%S.') + str(1000 + current_time.microsecond % 1000)[-3:]
class GlcData:
def __init__(self, logLevel = ''):
self.text = ''
self.date = get_current_time()
self.system = os.getenv('GLC_SYSTEM')
self.serverName = get_server_name()
self.serverIp = get_intranet_ip()
self.clientIp = ''
self.traceId = os.getenv('GLC_TRACE_ID')
self.user = ''
def post_glc_data(glc_data, logLevel):
if not glc_data:
return
url = os.getenv('GLC_API_URL')
if url is None:
# 不发日志中心就打印日志,否则不打印
print(get_current_time(), logLevel, glc_data.text)
return
data = {
'text': glc_data.text,
'date': glc_data.date,
'system': glc_data.system,
'servername': glc_data.serverName,
'serverip': glc_data.serverIp,
'clientip': glc_data.clientIp,
'traceid': glc_data.traceId,
'loglevel': logLevel,
'user': glc_data.user
}
json_data = json.dumps(data)
headers = {'Content-Type': 'application/json', 'X-GLC-AUTH': 'glogcenter'}
if os.getenv('GLC_API_KEY') is not None:
headers['X-GLC-AUTH'] = os.getenv('GLC_API_KEY')
requests.post(url, data=json_data, headers=headers)
def argsToGlcData(*args):
text = ''
glc_data = None
# 将非空且非GlcData实例的参数转换为字符串并拼接
for arg in args:
if arg is not None and not isinstance(arg, GlcData):
text += ' ' + str(arg)
text = text.strip()
# 无内容时返回空
if text == '':
return None
# 处理GlcData实例参数
glc_args = [arg for arg in args if isinstance(arg, GlcData)]
if glc_args:
# 如果有GlcData实例参数取出最后一个作为glc_data
glc_data = glc_args[-1]
else:
# 如果没有GlcData实例参数新建一个GlcdData实例
glc_data = GlcData()
# 将第一步得到的text赋值给glc_data的text属性
glc_data.text = text
# 相应字段为空时设定默认值
if glc_data.system == '':
glc_data.system = 'default'
if glc_data.traceId == '':
glc_data.traceId = hash_string(str(random.randint(10000, sys.maxsize)))
return glc_data
def debug(*args):
post_glc_data(argsToGlcData(*args), 'DEBUG')
def info(*args):
post_glc_data(argsToGlcData(*args), 'INFO')
def warn(*args):
post_glc_data(argsToGlcData(*args), 'WARN')
def error(*args):
post_glc_data(argsToGlcData(*args), 'ERROR')

131
glc-python-client/setup.py Normal file
View File

@@ -0,0 +1,131 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Note: To use the 'upload' functionality of this file, you must:
# $ pipenv install twine --dev
import io
import os
import sys
from shutil import rmtree
from setuptools import find_packages, setup, Command
# Package meta-data.
NAME = 'glogcenter'
DESCRIPTION = 'glogcenter 的 python 版客户端'
URL = 'https://github.com/gotoeasy/glogcenter'
EMAIL = 'gotoeasy@163.com'
AUTHOR = 'gotoeasy'
REQUIRES_PYTHON = '>=3.6.0'
VERSION = '0.1.8'
# What packages are required for this module to be executed?
REQUIRED = [
'requests', 'netifaces'
]
# What packages are optional?
EXTRAS = {
# 'fancy feature': ['django'],
}
# The rest you shouldn't have to touch too much :)
# ------------------------------------------------
# Except, perhaps the License and Trove Classifiers!
# If you do change the License, remember to change the Trove Classifier for that!
here = os.path.abspath(os.path.dirname(__file__))
# Import the README and use it as the long-description.
# Note: this will only work if 'README.md' is present in your MANIFEST.in file!
try:
with io.open(os.path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = '\n' + f.read()
except FileNotFoundError:
long_description = DESCRIPTION
# Load the package's __version__.py module as a dictionary.
about = {}
if not VERSION:
project_slug = NAME.lower().replace("-", "_").replace(" ", "_")
with open(os.path.join(here, project_slug, '__version__.py')) as f:
exec(f.read(), about)
else:
about['__version__'] = VERSION
class UploadCommand(Command):
"""Support setup.py upload."""
description = 'Build and publish the package.'
user_options = []
@staticmethod
def status(s):
"""Prints things in bold."""
print('\033[1m{0}\033[0m'.format(s))
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
try:
self.status('Removing previous builds…')
rmtree(os.path.join(here, 'dist'))
except OSError:
pass
self.status('Building Source and Wheel (universal) distribution…')
os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable))
self.status('Uploading the package to PyPI via Twine…')
os.system('twine upload dist/*')
self.status('Pushing git tags…')
os.system('git tag v{0}'.format(about['__version__']))
os.system('git push --tags')
sys.exit()
# Where the magic happens:
setup(
name=NAME,
version=about['__version__'],
description=DESCRIPTION,
long_description=long_description,
long_description_content_type='text/markdown',
author=AUTHOR,
author_email=EMAIL,
python_requires=REQUIRES_PYTHON,
url=URL,
packages=find_packages(exclude=["tests", "*.tests", "*.tests.*", "tests.*"]),
# If your package is a single module, use this instead of 'packages':
# py_modules=['mypackage'],
# entry_points={
# 'console_scripts': ['mycli=mymodule:cli'],
# },
install_requires=REQUIRED,
extras_require=EXTRAS,
include_package_data=True,
license='MIT',
classifiers=[
# Trove classifiers
# Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy'
],
# $ setup.py publish support.
cmdclass={
'upload': UploadCommand,
},
)