Skip to content

Commit 3c4845a

Browse files
authored
Update to v0.2.0
Python 3.7 support dropped. Abstract classes extended. Tests are extended.
2 parents 7a72e5c + 5db1646 commit 3c4845a

10 files changed

Lines changed: 110 additions & 37 deletions

File tree

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
python-version: [3.7, 3.8, 3.9]
15+
python-version: [3.8, 3.9]
1616

1717
steps:
1818
- uses: actions/checkout@v2

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This utility is an alternative for the built-in `logging` utility.
77

88
## Installation
99

10-
Requires python version 3.7 or later.
10+
Requires python version 3.8 or later.
1111

1212
To install the latest release on [PyPI](https://pypi.org/project/python-fslogger/),
1313
simply run:

fsLogger/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from __future__ import annotations
2-
__version__ = "0.1.7"
1+
__version__ = "0.2.0"
32
__doc__ = """
43
Logging utility v{}
54
Copyright (C) 2021 Fusion Solutions KFT <contact@fusionsolutions.io>
@@ -26,7 +25,7 @@
2625
from .filter import Filter, FilterParser
2726
from .logger import Logger
2827
from .loggerManager import LoggerManager, DowngradedLoggerManager
29-
from .abcs import T_LoggerManager
28+
from .abcs import T_Logger, T_LoggerManager
3029
# Program
3130
def SimpleLogger(level:Union[str, int]="TRACE") -> T_LoggerManager:
3231
lm:T_LoggerManager
@@ -45,4 +44,5 @@ def downgradeLoggerManager() -> T_LoggerManager:
4544
lm = cast(T_LoggerManager, _GlobHandler.get())
4645
return lm
4746

48-
__all__ = "LoggerManager", "Logger", "Levels", "Filter", "FilterParser", "SimpleLogger", "downgradeLoggerManager"
47+
__all__ = ("LoggerManager", "Logger", "Levels", "Filter", "FilterParser", "SimpleLogger", "downgradeLoggerManager", "T_Logger",
48+
"T_LoggerManager")

fsLogger/abcs.py

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,79 @@
33
from abc import ABCMeta, abstractmethod
44
from threading import RLock
55
# from socket import socket
6-
from typing import Dict, Tuple, Optional, Any, List
6+
from typing import Dict, Tuple, Optional, Any, List, Union, OrderedDict
77
# Third party modules
88
# Local modules
99
# Program
10+
class T_Logger(metaclass=ABCMeta):
11+
@abstractmethod
12+
def getChild(self, *name:str) -> T_Logger: ...
13+
@abstractmethod
14+
def isFiltered(self, levelID:Union[int, str]) -> bool: ...
15+
@abstractmethod
16+
def trace(self, message:str, *args:Any, **kwargs:Any) -> None: ...
17+
@abstractmethod
18+
def debug(self, message:str, *args:Any, **kwargs:Any) -> None: ...
19+
@abstractmethod
20+
def info(self, message:str, *args:Any, **kwargs:Any) -> None: ...
21+
@abstractmethod
22+
def warn(self, message:str, *args:Any, **kwargs:Any) -> None: ...
23+
@abstractmethod
24+
def warning(self, message:str, *args:Any, **kwargs:Any) -> None: ...
25+
@abstractmethod
26+
def error(self, message:str, *args:Any, **kwargs:Any) -> None: ...
27+
@abstractmethod
28+
def critical(self, message:str, *args:Any, **kwargs:Any) -> None: ...
29+
@abstractmethod
30+
def fatal(self, message:str, *args:Any, **kwargs:Any) -> None: ...
31+
32+
class T_Filter(metaclass=ABCMeta):
33+
keys:OrderedDict[str, T_Filter]
34+
fallbackLevel:int
35+
@abstractmethod
36+
def addLogger(self, k:str, v:T_Filter) -> T_Filter: ...
37+
@abstractmethod
38+
def setFallbackLevel(self, level:Union[int, str]) -> None: ...
39+
@abstractmethod
40+
def getKey(self, k:str) -> Optional[T_Filter]: ...
41+
@abstractmethod
42+
def getFilteredID(self, path:List[str]) -> int: ...
43+
@abstractmethod
44+
def dump(self) -> List[Any]: ...
45+
@abstractmethod
46+
def extend(self, inp:T_Filter) -> None: ...
47+
1048
class T_LoggerManager(metaclass=ABCMeta):
1149
lock:RLock
12-
handler:Optional[T_LoggerManager]
1350
filterChangeTime:float
1451
groupSeperator:str
52+
handler:Optional[T_LoggerManager]
53+
filter:T_Filter
54+
delta:float
55+
messageFormat:str
56+
dateFormat:str
1557
modules:List[T_ModuleBase]
1658
@abstractmethod
59+
def getFilterData(self, name:str) -> Tuple[float, int]: ...
60+
@abstractmethod
61+
def emit(self, name:str, levelID:int, timestamp:float, message:Any, _args:Tuple[Any, ...],
62+
_kwargs:Dict[str, Any]) -> None: ...
63+
@abstractmethod
64+
def extendFilter(self, data:Union[List[Any], str, T_Filter]) -> None: ...
65+
@abstractmethod
1766
def close(self, ) -> None: ...
1867
@abstractmethod
19-
def emit(self, name:str, levelID:int, timestamp:float, message:Any, _args:Tuple[Any, ...], _kwargs:Dict[str, Any]) -> None: ...
68+
def messageFormatter(self, name:str, levelID:int, timestamp:float, message:str, _args:Tuple[Any, ...],
69+
_kwargs:Dict[str, Any], datetime:Any=...) -> str: ...
2070
@abstractmethod
21-
def getFilterData(self, name:str) -> Tuple[float, int]: ...
71+
def initStandardOutStream(self) -> None: ...
72+
@abstractmethod
73+
def initFileStream(self, fullPath:str) -> None: ...
74+
@abstractmethod
75+
def initRotatedFileStream(self, fullPath:str, maxBytes:int=..., rotateDaily:bool=...,
76+
maxBackup:Optional[int]=...) -> None: ...
77+
@abstractmethod
78+
def initDailyFileStream(self, logPath:str, prefix:str, postfix:str, dateFormat:str=...) -> None: ...
2279

2380
class T_ModuleBase(metaclass=ABCMeta):
2481
@abstractmethod

fsLogger/filter.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
# Builtin modules
22
from __future__ import annotations
33
from fnmatch import fnmatchcase
4-
from typing import Dict, List, Any, Union, Optional, cast
4+
from typing import List, Any, Union, Optional, cast
55
from collections import OrderedDict
66
# Third party modules
77
# Local modules
8+
from .abcs import T_Filter
89
from .globHandler import _GlobHandler
910
from .levels import Levels
1011
# Program
11-
class Filter:
12-
keys:Dict[str, Filter]
13-
fallbackLevel:int
12+
class Filter(T_Filter):
1413
__slots__ = ("keys", "fallbackLevel")
1514
def __init__(self, fallbackLevel:int) -> None:
16-
self.keys = cast(Dict[str, Filter], OrderedDict())
15+
self.keys = OrderedDict()
1716
self.fallbackLevel = fallbackLevel
18-
def addLogger(self, k:str, v:Filter) -> Filter:
17+
def addLogger(self, k:str, v:T_Filter) -> T_Filter:
1918
self.keys[k] = v
2019
return self
2120
def setFallbackLevel(self, level:Union[int, str]) -> None:
2221
self.fallbackLevel = Levels.parse(level)
2322
return None
24-
def getKey(self, k:str) -> Optional[Filter]:
23+
def getKey(self, k:str) -> Optional[T_Filter]:
2524
return self.keys[k.lower()] if k.lower() in self.keys else None
2625
def getFilteredID(self, path:List[str]) -> int:
2726
name = path.pop(0)
@@ -37,7 +36,7 @@ def dump(self) -> List[Any]:
3736
for key, val in self.keys.items():
3837
ret.append({ key:val.dump() })
3938
return ret
40-
def extend(self, inp:Filter) -> None:
39+
def extend(self, inp:T_Filter) -> None:
4140
if inp.fallbackLevel != 0:
4241
self.fallbackLevel = inp.fallbackLevel
4342
for key, val in inp.keys.items():
@@ -51,7 +50,7 @@ def extend(self, inp:Filter) -> None:
5150

5251
class FilterParser:
5352
@staticmethod
54-
def fromString(data:str) -> Filter:
53+
def fromString(data:str) -> T_Filter:
5554
"""
5655
parent:ERROR,parent.children.son:WARNING
5756
->
@@ -68,7 +67,7 @@ def fromString(data:str) -> Filter:
6867
]}
6968
]
7069
"""
71-
lastScope:Filter
70+
lastScope:T_Filter
7271
ret = Filter(0)
7372
for part in data.lower().split(","):
7473
rawPaths, levelID = part.split(":")
@@ -80,7 +79,7 @@ def fromString(data:str) -> Filter:
8079
lastScope = lastScope.keys[path]
8180
return ret
8281
@classmethod
83-
def fromJson(cls, datas:List[Any]) -> Filter:
82+
def fromJson(cls, datas:List[Any]) -> T_Filter:
8483
"""
8584
[
8685
{ "parent": [

fsLogger/logger.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
# Builtin modules
2-
from __future__ import annotations
32
from typing import Dict, Any, Union
43
from time import time
54
# Third party modules
65
# Local modules
6+
from .abcs import T_Logger
77
from .globHandler import _GlobHandler
88
from .levels import Levels
99
# Program
10-
class Logger:
10+
class Logger(T_Logger):
1111
name:str
1212
filterChangeTime:float
1313
lastFilterLevel:int
1414
__slots__ = ( "name", "filterChangeTime", "lastFilterLevel" )
15-
def __init__(self, name:Union[str, Logger]):
15+
def __init__(self, name:Union[str, T_Logger]):
1616
if isinstance(name, Logger):
1717
name = name.name
1818
self.__setstate__({ "name":name, "filterChangeTime":0, "lastFilterLevel":0 })
@@ -26,8 +26,8 @@ def __setstate__(self, states:Dict[str, Any]) -> None:
2626
self.name = states["name"]
2727
self.filterChangeTime = states["filterChangeTime"]
2828
self.lastFilterLevel = states["lastFilterLevel"]
29-
def getChild(self, name:str) -> Logger:
30-
return Logger("{}{}{}".format(self.name, _GlobHandler.getGroupSeperator(), name))
29+
def getChild(self, *name:str) -> T_Logger:
30+
return Logger(_GlobHandler.getGroupSeperator().join([self.name] + list(name)))
3131
def isFiltered(self, levelID:Union[int, str]) -> bool:
3232
if self.filterChangeTime != _GlobHandler.getFilterChangeTime():
3333
self.filterChangeTime, self.lastFilterLevel = _GlobHandler.getFilterData(self.name)

fsLogger/loggerManager.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# Third party modules
99
# Local modules
1010
from .globHandler import _GlobHandler
11-
from .abcs import T_LoggerManager
11+
from .abcs import T_Filter, T_LoggerManager
1212
from .filter import Filter, FilterParser
1313
from .modules import STDOutStreamingModule, STDErrModule, STDOutModule, FileStream, RotatedFileStream, DailyFileStream
1414
from .levels import Levels
@@ -24,7 +24,7 @@ class LoggerManager(T_LoggerManager):
2424
@staticmethod
2525
def getHandler() -> Optional[T_LoggerManager]:
2626
return _GlobHandler.get()
27-
def __init__(self, filter:Optional[Union[List[Any], str, Filter]]=None, messageFormat:str=DEF_FORMAT,
27+
def __init__(self, filter:Optional[Union[List[Any], str, T_Filter]]=None, messageFormat:str=DEF_FORMAT,
2828
dateFormat:str=DEF_DATE, defaultLevel:Optional[Union[int, str]]=None, hookSTDOut:bool=True, hookSTDErr:bool=True):
2929
_GlobHandler.activate(self)
3030
self.filter = Filter(Levels.parse(DEF_LEVEL if defaultLevel is None else defaultLevel ))
@@ -56,13 +56,13 @@ def emit(self, name:str, levelID:int, timestamp:float, message:Any, _args:Tuple[
5656
for handler in self.modules:
5757
try: handler.emit(parsedMessage)
5858
except: pass
59-
def extendFilter(self, data:Union[List[Any], str, Filter]) -> None:
60-
filter = Filter(0)
59+
def extendFilter(self, data:Union[List[Any], str, T_Filter]) -> None:
60+
filter:T_Filter = Filter(0)
6161
if isinstance(data, list):
6262
filter = FilterParser.fromJson(data)
6363
elif isinstance(data, str):
6464
filter = FilterParser.fromString(data)
65-
assert isinstance(filter, Filter)
65+
assert isinstance(filter, T_Filter)
6666
self.filter.extend(filter)
6767
def close(self) -> None:
6868
for module in self.modules:

fsLogger/modules.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
from typing import List, Tuple, Any, Optional
88
# Third party modules
99
# Local modules
10-
from .abcs import T_ModuleBase
10+
from .abcs import T_Logger, T_ModuleBase
1111
from .logger import Logger
1212
# Program
1313
class STDErrModule:
14-
log:Logger
14+
log:T_Logger
1515
closed:bool
1616
buffer:str
1717
def __init__(self) -> None:
@@ -34,7 +34,7 @@ def close(self) -> None:
3434
self.closed = True
3535

3636
class STDOutModule:
37-
log:Logger
37+
log:T_Logger
3838
closed:bool
3939
buffer:str
4040
def __init__(self) -> None:

fsLogger/test/loggerManager.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def test(self) -> None:
3636
with open(fn, "rt") as fid:
3737
self.assertEqual(fid.read(), "[INF][test] : Hello\n")
3838
lm.close()
39+
#
3940
lm = LoggerManager(
4041
messageFormat="[{levelshortname}][{name}] : {message}\n",
4142
defaultLevel="TRACE",
@@ -51,6 +52,23 @@ def test(self) -> None:
5152
with open(fn, "rt") as fid:
5253
self.assertEqual(fid.read(), "[INF][Standard.Output] : Hello\n[INF][Standard.Output] : Hello\n")
5354
lm.close()
55+
#
56+
lm = LoggerManager(
57+
messageFormat="[{levelshortname}][{name}] : {message}\n",
58+
defaultLevel="TRACE",
59+
hookSTDOut=True,
60+
hookSTDErr=False
61+
)
62+
with TemporaryDirectory() as tmpdir:
63+
fn = "{}/teszt.log".format(tmpdir)
64+
lm.initFileStream(fn)
65+
Logger("some").info("Hello")
66+
Logger("some").getChild("module").info("Hello")
67+
Logger("some").getChild("module", "sub").info("Hello")
68+
with open(fn, "rt") as fid:
69+
self.assertEqual(fid.read(),"[INF][some] : Hello\n[INF][some.module] : Hello\n[INF][some.module.sub] : Hello\n")
70+
lm.close()
71+
#
5472
lm = LoggerManager(
5573
messageFormat="[{levelshortname}][{name}] : {message}\n",
5674
defaultLevel="TRACE",

setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
setup(
1111
name = "python-fslogger",
12-
version = "0.1.7",
12+
version = "0.2.0",
1313
description = "Logging utility",
1414
keywords = "logging utility fusion solutions fusionsolutions",
1515
author = "Andor `iFA` Rajci - Fusions Solutions KFT",
@@ -20,14 +20,13 @@
2020
long_description = open(os.path.join(pwd, "README.md")).read(),
2121
long_description_content_type = "text/markdown",
2222
zip_safe = False,
23-
python_requires = ">=3.7.0",
23+
python_requires = ">=3.8.0",
2424
test_suite = "fsLogger.test",
2525
package_data = { "":["py.typed"] },
2626
classifiers = [ # https://pypi.org/pypi?%3Aaction=list_classifiers
2727
"Development Status :: 4 - Beta",
2828
"Topic :: Utilities",
2929
"Programming Language :: Python :: 3 :: Only",
30-
"Programming Language :: Python :: 3.7",
3130
"Programming Language :: Python :: 3.8",
3231
"Programming Language :: Python :: 3.9",
3332
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",

0 commit comments

Comments
 (0)