ominfra 0.0.0.dev157__py3-none-any.whl → 0.0.0.dev158__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -142,9 +142,9 @@ InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings']
142
142
  ConfigMapping = ta.Mapping[str, ta.Any]
143
143
 
144
144
  # ../../omlish/http/handlers.py
145
- HttpHandler = ta.Callable[['HttpHandlerRequest'], 'HttpHandlerResponse']
145
+ HttpHandler = ta.Callable[['HttpHandlerRequest'], 'HttpHandlerResponse'] # ta.TypeAlias
146
146
 
147
- # ../../omlish/http/coroserver.py
147
+ # ../../omlish/http/coro/server.py
148
148
  CoroHttpServerFactory = ta.Callable[[SocketAddress], 'CoroHttpServer']
149
149
 
150
150
 
@@ -2202,6 +2202,13 @@ json_dump_compact: ta.Callable[..., bytes] = functools.partial(json.dump, **JSON
2202
2202
  json_dumps_compact: ta.Callable[..., str] = functools.partial(json.dumps, **JSON_COMPACT_KWARGS)
2203
2203
 
2204
2204
 
2205
+ ########################################
2206
+ # ../../../omlish/lite/logs.py
2207
+
2208
+
2209
+ log = logging.getLogger(__name__)
2210
+
2211
+
2205
2212
  ########################################
2206
2213
  # ../../../omlish/lite/maybes.py
2207
2214
 
@@ -2486,6 +2493,116 @@ class Func3(ta.Generic[A0, A1, A2, T]):
2486
2493
  return self.fn(a0, a1, a2)
2487
2494
 
2488
2495
 
2496
+ ########################################
2497
+ # ../../../omlish/logs/filters.py
2498
+
2499
+
2500
+ class TidLogFilter(logging.Filter):
2501
+ def filter(self, record):
2502
+ record.tid = threading.get_native_id()
2503
+ return True
2504
+
2505
+
2506
+ ########################################
2507
+ # ../../../omlish/logs/proxy.py
2508
+
2509
+
2510
+ class ProxyLogFilterer(logging.Filterer):
2511
+ def __init__(self, underlying: logging.Filterer) -> None: # noqa
2512
+ self._underlying = underlying
2513
+
2514
+ @property
2515
+ def underlying(self) -> logging.Filterer:
2516
+ return self._underlying
2517
+
2518
+ @property
2519
+ def filters(self):
2520
+ return self._underlying.filters
2521
+
2522
+ @filters.setter
2523
+ def filters(self, filters):
2524
+ self._underlying.filters = filters
2525
+
2526
+ def addFilter(self, filter): # noqa
2527
+ self._underlying.addFilter(filter)
2528
+
2529
+ def removeFilter(self, filter): # noqa
2530
+ self._underlying.removeFilter(filter)
2531
+
2532
+ def filter(self, record):
2533
+ return self._underlying.filter(record)
2534
+
2535
+
2536
+ class ProxyLogHandler(ProxyLogFilterer, logging.Handler):
2537
+ def __init__(self, underlying: logging.Handler) -> None: # noqa
2538
+ ProxyLogFilterer.__init__(self, underlying)
2539
+
2540
+ _underlying: logging.Handler
2541
+
2542
+ @property
2543
+ def underlying(self) -> logging.Handler:
2544
+ return self._underlying
2545
+
2546
+ def get_name(self):
2547
+ return self._underlying.get_name()
2548
+
2549
+ def set_name(self, name):
2550
+ self._underlying.set_name(name)
2551
+
2552
+ @property
2553
+ def name(self):
2554
+ return self._underlying.name
2555
+
2556
+ @property
2557
+ def level(self):
2558
+ return self._underlying.level
2559
+
2560
+ @level.setter
2561
+ def level(self, level):
2562
+ self._underlying.level = level
2563
+
2564
+ @property
2565
+ def formatter(self):
2566
+ return self._underlying.formatter
2567
+
2568
+ @formatter.setter
2569
+ def formatter(self, formatter):
2570
+ self._underlying.formatter = formatter
2571
+
2572
+ def createLock(self):
2573
+ self._underlying.createLock()
2574
+
2575
+ def acquire(self):
2576
+ self._underlying.acquire()
2577
+
2578
+ def release(self):
2579
+ self._underlying.release()
2580
+
2581
+ def setLevel(self, level):
2582
+ self._underlying.setLevel(level)
2583
+
2584
+ def format(self, record):
2585
+ return self._underlying.format(record)
2586
+
2587
+ def emit(self, record):
2588
+ self._underlying.emit(record)
2589
+
2590
+ def handle(self, record):
2591
+ return self._underlying.handle(record)
2592
+
2593
+ def setFormatter(self, fmt):
2594
+ self._underlying.setFormatter(fmt)
2595
+
2596
+ def flush(self):
2597
+ self._underlying.flush()
2598
+
2599
+ def close(self):
2600
+ self._underlying.close()
2601
+
2602
+ def handleError(self, record):
2603
+ self._underlying.handleError(record)
2604
+
2605
+
2489
2606
  ########################################
2490
2607
  # ../events.py
2491
2608
 
@@ -4733,367 +4850,97 @@ inj = Injection
4733
4850
 
4734
4851
 
4735
4852
  ########################################
4736
- # ../../../omlish/lite/logs.py
4853
+ # ../../../omlish/lite/marshal.py
4737
4854
  """
4738
4855
  TODO:
4739
- - translate json keys
4740
- - debug
4856
+ - pickle stdlib objs? have to pin to 3.8 pickle protocol, will be cross-version
4857
+ - namedtuple
4858
+ - literals
4859
+ - newtypes?
4741
4860
  """
4742
4861
 
4743
4862
 
4744
- log = logging.getLogger(__name__)
4745
-
4746
-
4747
4863
  ##
4748
4864
 
4749
4865
 
4750
- class TidLogFilter(logging.Filter):
4751
-
4752
- def filter(self, record):
4753
- record.tid = threading.get_native_id()
4754
- return True
4866
+ @dc.dataclass(frozen=True)
4867
+ class ObjMarshalOptions:
4868
+ raw_bytes: bool = False
4869
+ nonstrict_dataclasses: bool = False
4755
4870
 
4756
4871
 
4757
- ##
4872
+ class ObjMarshaler(abc.ABC):
4873
+ @abc.abstractmethod
4874
+ def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4875
+ raise NotImplementedError
4758
4876
 
4877
+ @abc.abstractmethod
4878
+ def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4879
+ raise NotImplementedError
4759
4880
 
4760
- class JsonLogFormatter(logging.Formatter):
4761
4881
 
4762
- KEYS: ta.Mapping[str, bool] = {
4763
- 'name': False,
4764
- 'msg': False,
4765
- 'args': False,
4766
- 'levelname': False,
4767
- 'levelno': False,
4768
- 'pathname': False,
4769
- 'filename': False,
4770
- 'module': False,
4771
- 'exc_info': True,
4772
- 'exc_text': True,
4773
- 'stack_info': True,
4774
- 'lineno': False,
4775
- 'funcName': False,
4776
- 'created': False,
4777
- 'msecs': False,
4778
- 'relativeCreated': False,
4779
- 'thread': False,
4780
- 'threadName': False,
4781
- 'processName': False,
4782
- 'process': False,
4783
- }
4882
+ class NopObjMarshaler(ObjMarshaler):
4883
+ def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4884
+ return o
4784
4885
 
4785
- def format(self, record: logging.LogRecord) -> str:
4786
- dct = {
4787
- k: v
4788
- for k, o in self.KEYS.items()
4789
- for v in [getattr(record, k)]
4790
- if not (o and v is None)
4791
- }
4792
- return json_dumps_compact(dct)
4886
+ def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4887
+ return o
4793
4888
 
4794
4889
 
4795
- ##
4890
+ @dc.dataclass()
4891
+ class ProxyObjMarshaler(ObjMarshaler):
4892
+ m: ta.Optional[ObjMarshaler] = None
4796
4893
 
4894
+ def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4895
+ return check.not_none(self.m).marshal(o, ctx)
4797
4896
 
4798
- STANDARD_LOG_FORMAT_PARTS = [
4799
- ('asctime', '%(asctime)-15s'),
4800
- ('process', 'pid=%(process)-6s'),
4801
- ('thread', 'tid=%(thread)x'),
4802
- ('levelname', '%(levelname)s'),
4803
- ('name', '%(name)s'),
4804
- ('separator', '::'),
4805
- ('message', '%(message)s'),
4806
- ]
4897
+ def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4898
+ return check.not_none(self.m).unmarshal(o, ctx)
4807
4899
 
4808
4900
 
4809
- class StandardLogFormatter(logging.Formatter):
4901
+ @dc.dataclass(frozen=True)
4902
+ class CastObjMarshaler(ObjMarshaler):
4903
+ ty: type
4810
4904
 
4811
- @staticmethod
4812
- def build_log_format(parts: ta.Iterable[ta.Tuple[str, str]]) -> str:
4813
- return ' '.join(v for k, v in parts)
4905
+ def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4906
+ return o
4814
4907
 
4815
- converter = datetime.datetime.fromtimestamp # type: ignore
4908
+ def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4909
+ return self.ty(o)
4816
4910
 
4817
- def formatTime(self, record, datefmt=None):
4818
- ct = self.converter(record.created) # type: ignore
4819
- if datefmt:
4820
- return ct.strftime(datefmt) # noqa
4821
- else:
4822
- t = ct.strftime('%Y-%m-%d %H:%M:%S')
4823
- return '%s.%03d' % (t, record.msecs) # noqa
4824
4911
 
4912
+ class DynamicObjMarshaler(ObjMarshaler):
4913
+ def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4914
+ return ctx.manager.marshal_obj(o, opts=ctx.options)
4825
4915
 
4826
- ##
4916
+ def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4917
+ return o
4827
4918
 
4828
4919
 
4829
- class ProxyLogFilterer(logging.Filterer):
4830
- def __init__(self, underlying: logging.Filterer) -> None: # noqa
4831
- self._underlying = underlying
4920
+ @dc.dataclass(frozen=True)
4921
+ class Base64ObjMarshaler(ObjMarshaler):
4922
+ ty: type
4832
4923
 
4833
- @property
4834
- def underlying(self) -> logging.Filterer:
4835
- return self._underlying
4924
+ def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4925
+ return base64.b64encode(o).decode('ascii')
4836
4926
 
4837
- @property
4838
- def filters(self):
4839
- return self._underlying.filters
4927
+ def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4928
+ return self.ty(base64.b64decode(o))
4840
4929
 
4841
- @filters.setter
4842
- def filters(self, filters):
4843
- self._underlying.filters = filters
4844
4930
 
4845
- def addFilter(self, filter): # noqa
4846
- self._underlying.addFilter(filter)
4931
+ @dc.dataclass(frozen=True)
4932
+ class BytesSwitchedObjMarshaler(ObjMarshaler):
4933
+ m: ObjMarshaler
4847
4934
 
4848
- def removeFilter(self, filter): # noqa
4849
- self._underlying.removeFilter(filter)
4935
+ def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4936
+ if ctx.options.raw_bytes:
4937
+ return o
4938
+ return self.m.marshal(o, ctx)
4850
4939
 
4851
- def filter(self, record):
4852
- return self._underlying.filter(record)
4853
-
4854
-
4855
- class ProxyLogHandler(ProxyLogFilterer, logging.Handler):
4856
- def __init__(self, underlying: logging.Handler) -> None: # noqa
4857
- ProxyLogFilterer.__init__(self, underlying)
4858
-
4859
- _underlying: logging.Handler
4860
-
4861
- @property
4862
- def underlying(self) -> logging.Handler:
4863
- return self._underlying
4864
-
4865
- def get_name(self):
4866
- return self._underlying.get_name()
4867
-
4868
- def set_name(self, name):
4869
- self._underlying.set_name(name)
4870
-
4871
- @property
4872
- def name(self):
4873
- return self._underlying.name
4874
-
4875
- @property
4876
- def level(self):
4877
- return self._underlying.level
4878
-
4879
- @level.setter
4880
- def level(self, level):
4881
- self._underlying.level = level
4882
-
4883
- @property
4884
- def formatter(self):
4885
- return self._underlying.formatter
4886
-
4887
- @formatter.setter
4888
- def formatter(self, formatter):
4889
- self._underlying.formatter = formatter
4890
-
4891
- def createLock(self):
4892
- self._underlying.createLock()
4893
-
4894
- def acquire(self):
4895
- self._underlying.acquire()
4896
-
4897
- def release(self):
4898
- self._underlying.release()
4899
-
4900
- def setLevel(self, level):
4901
- self._underlying.setLevel(level)
4902
-
4903
- def format(self, record):
4904
- return self._underlying.format(record)
4905
-
4906
- def emit(self, record):
4907
- self._underlying.emit(record)
4908
-
4909
- def handle(self, record):
4910
- return self._underlying.handle(record)
4911
-
4912
- def setFormatter(self, fmt):
4913
- self._underlying.setFormatter(fmt)
4914
-
4915
- def flush(self):
4916
- self._underlying.flush()
4917
-
4918
- def close(self):
4919
- self._underlying.close()
4920
-
4921
- def handleError(self, record):
4922
- self._underlying.handleError(record)
4923
-
4924
-
4925
- ##
4926
-
4927
-
4928
- class StandardLogHandler(ProxyLogHandler):
4929
- pass
4930
-
4931
-
4932
- ##
4933
-
4934
-
4935
- @contextlib.contextmanager
4936
- def _locking_logging_module_lock() -> ta.Iterator[None]:
4937
- if hasattr(logging, '_acquireLock'):
4938
- logging._acquireLock() # noqa
4939
- try:
4940
- yield
4941
- finally:
4942
- logging._releaseLock() # type: ignore # noqa
4943
-
4944
- elif hasattr(logging, '_lock'):
4945
- # https://github.com/python/cpython/commit/74723e11109a320e628898817ab449b3dad9ee96
4946
- with logging._lock: # noqa
4947
- yield
4948
-
4949
- else:
4950
- raise Exception("Can't find lock in logging module")
4951
-
4952
-
4953
- def configure_standard_logging(
4954
- level: ta.Union[int, str] = logging.INFO,
4955
- *,
4956
- json: bool = False,
4957
- target: ta.Optional[logging.Logger] = None,
4958
- force: bool = False,
4959
- handler_factory: ta.Optional[ta.Callable[[], logging.Handler]] = None,
4960
- ) -> ta.Optional[StandardLogHandler]:
4961
- with _locking_logging_module_lock():
4962
- if target is None:
4963
- target = logging.root
4964
-
4965
- #
4966
-
4967
- if not force:
4968
- if any(isinstance(h, StandardLogHandler) for h in list(target.handlers)):
4969
- return None
4970
-
4971
- #
4972
-
4973
- if handler_factory is not None:
4974
- handler = handler_factory()
4975
- else:
4976
- handler = logging.StreamHandler()
4977
-
4978
- #
4979
-
4980
- formatter: logging.Formatter
4981
- if json:
4982
- formatter = JsonLogFormatter()
4983
- else:
4984
- formatter = StandardLogFormatter(StandardLogFormatter.build_log_format(STANDARD_LOG_FORMAT_PARTS))
4985
- handler.setFormatter(formatter)
4986
-
4987
- #
4988
-
4989
- handler.addFilter(TidLogFilter())
4990
-
4991
- #
4992
-
4993
- target.addHandler(handler)
4994
-
4995
- #
4996
-
4997
- if level is not None:
4998
- target.setLevel(level)
4999
-
5000
- #
5001
-
5002
- return StandardLogHandler(handler)
5003
-
5004
-
5005
- ########################################
5006
- # ../../../omlish/lite/marshal.py
5007
- """
5008
- TODO:
5009
- - pickle stdlib objs? have to pin to 3.8 pickle protocol, will be cross-version
5010
- - namedtuple
5011
- - literals
5012
- - newtypes?
5013
- """
5014
-
5015
-
5016
- ##
5017
-
5018
-
5019
- @dc.dataclass(frozen=True)
5020
- class ObjMarshalOptions:
5021
- raw_bytes: bool = False
5022
- nonstrict_dataclasses: bool = False
5023
-
5024
-
5025
- class ObjMarshaler(abc.ABC):
5026
- @abc.abstractmethod
5027
- def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5028
- raise NotImplementedError
5029
-
5030
- @abc.abstractmethod
5031
- def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5032
- raise NotImplementedError
5033
-
5034
-
5035
- class NopObjMarshaler(ObjMarshaler):
5036
- def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5037
- return o
5038
-
5039
- def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5040
- return o
5041
-
5042
-
5043
- @dc.dataclass()
5044
- class ProxyObjMarshaler(ObjMarshaler):
5045
- m: ta.Optional[ObjMarshaler] = None
5046
-
5047
- def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5048
- return check.not_none(self.m).marshal(o, ctx)
5049
-
5050
- def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5051
- return check.not_none(self.m).unmarshal(o, ctx)
5052
-
5053
-
5054
- @dc.dataclass(frozen=True)
5055
- class CastObjMarshaler(ObjMarshaler):
5056
- ty: type
5057
-
5058
- def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5059
- return o
5060
-
5061
- def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5062
- return self.ty(o)
5063
-
5064
-
5065
- class DynamicObjMarshaler(ObjMarshaler):
5066
- def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5067
- return ctx.manager.marshal_obj(o, opts=ctx.options)
5068
-
5069
- def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5070
- return o
5071
-
5072
-
5073
- @dc.dataclass(frozen=True)
5074
- class Base64ObjMarshaler(ObjMarshaler):
5075
- ty: type
5076
-
5077
- def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5078
- return base64.b64encode(o).decode('ascii')
5079
-
5080
- def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5081
- return self.ty(base64.b64decode(o))
5082
-
5083
-
5084
- @dc.dataclass(frozen=True)
5085
- class BytesSwitchedObjMarshaler(ObjMarshaler):
5086
- m: ObjMarshaler
5087
-
5088
- def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5089
- if ctx.options.raw_bytes:
5090
- return o
5091
- return self.m.marshal(o, ctx)
5092
-
5093
- def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
5094
- if ctx.options.raw_bytes:
5095
- return o
5096
- return self.m.unmarshal(o, ctx)
4940
+ def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
4941
+ if ctx.options.raw_bytes:
4942
+ return o
4943
+ return self.m.unmarshal(o, ctx)
5097
4944
 
5098
4945
 
5099
4946
  @dc.dataclass(frozen=True)
@@ -5464,6 +5311,60 @@ def check_runtime_version() -> None:
5464
5311
  raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
5465
5312
 
5466
5313
 
5314
+ ########################################
5315
+ # ../../../omlish/logs/json.py
5316
+ """
5317
+ TODO:
5318
+ - translate json keys
5319
+ """
5320
+
5321
+
5322
+ class JsonLogFormatter(logging.Formatter):
5323
+ KEYS: ta.Mapping[str, bool] = {
5324
+ 'name': False,
5325
+ 'msg': False,
5326
+ 'args': False,
5327
+ 'levelname': False,
5328
+ 'levelno': False,
5329
+ 'pathname': False,
5330
+ 'filename': False,
5331
+ 'module': False,
5332
+ 'exc_info': True,
5333
+ 'exc_text': True,
5334
+ 'stack_info': True,
5335
+ 'lineno': False,
5336
+ 'funcName': False,
5337
+ 'created': False,
5338
+ 'msecs': False,
5339
+ 'relativeCreated': False,
5340
+ 'thread': False,
5341
+ 'threadName': False,
5342
+ 'processName': False,
5343
+ 'process': False,
5344
+ }
5345
+
5346
+ def __init__(
5347
+ self,
5348
+ *args: ta.Any,
5349
+ json_dumps: ta.Optional[ta.Callable[[ta.Any], str]] = None,
5350
+ **kwargs: ta.Any,
5351
+ ) -> None:
5352
+ super().__init__(*args, **kwargs)
5353
+
5354
+ if json_dumps is None:
5355
+ json_dumps = json_dumps_compact
5356
+ self._json_dumps = json_dumps
5357
+
5358
+ def format(self, record: logging.LogRecord) -> str:
5359
+ dct = {
5360
+ k: v
5361
+ for k, o in self.KEYS.items()
5362
+ for v in [getattr(record, k)]
5363
+ if not (o and v is None)
5364
+ }
5365
+ return self._json_dumps(dct)
5366
+
5367
+
5467
5368
  ########################################
5468
5369
  # ../../../omlish/os/journald.py
5469
5370
 
@@ -5852,6 +5753,126 @@ class UnsupportedMethodHttpHandlerError(Exception):
5852
5753
  pass
5853
5754
 
5854
5755
 
5756
+ ########################################
5757
+ # ../../../omlish/logs/standard.py
5758
+ """
5759
+ TODO:
5760
+ - structured
5761
+ - prefixed
5762
+ - debug
5763
+ """
5764
+
5765
+
5766
+ ##
5767
+
5768
+
5769
+ STANDARD_LOG_FORMAT_PARTS = [
5770
+ ('asctime', '%(asctime)-15s'),
5771
+ ('process', 'pid=%(process)-6s'),
5772
+ ('thread', 'tid=%(thread)x'),
5773
+ ('levelname', '%(levelname)s'),
5774
+ ('name', '%(name)s'),
5775
+ ('separator', '::'),
5776
+ ('message', '%(message)s'),
5777
+ ]
5778
+
5779
+
5780
+ class StandardLogFormatter(logging.Formatter):
5781
+ @staticmethod
5782
+ def build_log_format(parts: ta.Iterable[ta.Tuple[str, str]]) -> str:
5783
+ return ' '.join(v for k, v in parts)
5784
+
5785
+ converter = datetime.datetime.fromtimestamp # type: ignore
5786
+
5787
+ def formatTime(self, record, datefmt=None):
5788
+ ct = self.converter(record.created) # type: ignore
5789
+ if datefmt:
5790
+ return ct.strftime(datefmt) # noqa
5791
+ else:
5792
+ t = ct.strftime('%Y-%m-%d %H:%M:%S')
5793
+ return '%s.%03d' % (t, record.msecs) # noqa
5794
+
5795
+
5796
+ ##
5797
+
5798
+
5799
+ class StandardLogHandler(ProxyLogHandler):
5800
+ pass
5801
+
5802
+
5803
+ ##
5804
+
5805
+
5806
+ @contextlib.contextmanager
5807
+ def _locking_logging_module_lock() -> ta.Iterator[None]:
5808
+ if hasattr(logging, '_acquireLock'):
5809
+ logging._acquireLock() # noqa
5810
+ try:
5811
+ yield
5812
+ finally:
5813
+ logging._releaseLock() # type: ignore # noqa
5814
+
5815
+ elif hasattr(logging, '_lock'):
5816
+ # https://github.com/python/cpython/commit/74723e11109a320e628898817ab449b3dad9ee96
5817
+ with logging._lock: # noqa
5818
+ yield
5819
+
5820
+ else:
5821
+ raise Exception("Can't find lock in logging module")
5822
+
5823
+
5824
+ def configure_standard_logging(
5825
+ level: ta.Union[int, str] = logging.INFO,
5826
+ *,
5827
+ json: bool = False,
5828
+ target: ta.Optional[logging.Logger] = None,
5829
+ force: bool = False,
5830
+ handler_factory: ta.Optional[ta.Callable[[], logging.Handler]] = None,
5831
+ ) -> ta.Optional[StandardLogHandler]:
5832
+ with _locking_logging_module_lock():
5833
+ if target is None:
5834
+ target = logging.root
5835
+
5836
+ #
5837
+
5838
+ if not force:
5839
+ if any(isinstance(h, StandardLogHandler) for h in list(target.handlers)):
5840
+ return None
5841
+
5842
+ #
5843
+
5844
+ if handler_factory is not None:
5845
+ handler = handler_factory()
5846
+ else:
5847
+ handler = logging.StreamHandler()
5848
+
5849
+ #
5850
+
5851
+ formatter: logging.Formatter
5852
+ if json:
5853
+ formatter = JsonLogFormatter()
5854
+ else:
5855
+ formatter = StandardLogFormatter(StandardLogFormatter.build_log_format(STANDARD_LOG_FORMAT_PARTS))
5856
+ handler.setFormatter(formatter)
5857
+
5858
+ #
5859
+
5860
+ handler.addFilter(TidLogFilter())
5861
+
5862
+ #
5863
+
5864
+ target.addHandler(handler)
5865
+
5866
+ #
5867
+
5868
+ if level is not None:
5869
+ target.setLevel(level)
5870
+
5871
+ #
5872
+
5873
+ return StandardLogHandler(handler)
5874
+
5875
+
5855
5876
  ########################################
5856
5877
  # ../configs.py
5857
5878
 
@@ -6145,7 +6166,7 @@ def parse_logging_level(value: ta.Union[str, int]) -> int:
6145
6166
 
6146
6167
 
6147
6168
  ########################################
6148
- # ../../../omlish/http/coroserver.py
6169
+ # ../../../omlish/http/coro/server.py
6149
6170
  # PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
6150
6171
  # --------------------------------------------
6151
6172
  #
@@ -6885,7 +6906,7 @@ class ProcessGroup(
6885
6906
 
6886
6907
 
6887
6908
  ########################################
6888
- # ../../../omlish/io/fdio/corohttp.py
6909
+ # ../../../omlish/http/coro/fdio.py
6889
6910
 
6890
6911
 
6891
6912
  class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):