Remove support for the legacy structured logging configuration. (#12008)
parent
696acd3515
commit
e69f8f0a8e
|
@ -0,0 +1 @@
|
|||
Remove support for the legacy structured logging configuration (please see the the [upgrade notes](https://matrix-org.github.io/synapse/develop/upgrade#legacy-structured-logging-configuration-removal) if you are using `structured: true` in the Synapse configuration).
|
|
@ -81,14 +81,12 @@ remote endpoint at 10.1.2.3:9999.
|
|||
|
||||
## Upgrading from legacy structured logging configuration
|
||||
|
||||
Versions of Synapse prior to v1.23.0 included a custom structured logging
|
||||
configuration which is deprecated. It used a `structured: true` flag and
|
||||
configured `drains` instead of ``handlers`` and `formatters`.
|
||||
Versions of Synapse prior to v1.54.0 automatically converted the legacy
|
||||
structured logging configuration, which was deprecated in v1.23.0, to the standard
|
||||
library logging configuration.
|
||||
|
||||
Synapse currently automatically converts the old configuration to the new
|
||||
configuration, but this will be removed in a future version of Synapse. The
|
||||
following reference can be used to update your configuration. Based on the drain
|
||||
`type`, we can pick a new handler:
|
||||
The following reference can be used to update your configuration. Based on the
|
||||
drain `type`, we can pick a new handler:
|
||||
|
||||
1. For a type of `console`, `console_json`, or `console_json_terse`: a handler
|
||||
with a class of `logging.StreamHandler` and a `stream` of `ext://sys.stdout`
|
||||
|
|
|
@ -85,6 +85,15 @@ process, for example:
|
|||
dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
|
||||
```
|
||||
|
||||
# Upgrading to v1.54.0
|
||||
|
||||
## Legacy structured logging configuration removal
|
||||
|
||||
This release removes support for the `structured: true` logging configuration
|
||||
which was deprecated in Synapse v1.23.0. If your logging configuration contains
|
||||
`structured: true` then it should be modified based on the
|
||||
[structured logging documentation](structured_logging.md).
|
||||
|
||||
# Upgrading to v1.53.0
|
||||
|
||||
## Dropping support for `webclient` listeners and non-HTTP(S) `web_client_location`
|
||||
|
|
|
@ -33,7 +33,6 @@ from twisted.logger import (
|
|||
globalLogBeginner,
|
||||
)
|
||||
|
||||
from synapse.logging._structured import setup_structured_logging
|
||||
from synapse.logging.context import LoggingContextFilter
|
||||
from synapse.logging.filter import MetadataFilter
|
||||
|
||||
|
@ -138,6 +137,12 @@ Support for the log_file configuration option and --log-file command-line option
|
|||
removed in Synapse 1.3.0. You should instead set up a separate log configuration file.
|
||||
"""
|
||||
|
||||
STRUCTURED_ERROR = """\
|
||||
Support for the structured configuration option was removed in Synapse 1.54.0.
|
||||
You should instead use the standard logging configuration. See
|
||||
https://matrix-org.github.io/synapse/v1.54/structured_logging.html
|
||||
"""
|
||||
|
||||
|
||||
class LoggingConfig(Config):
|
||||
section = "logging"
|
||||
|
@ -292,10 +297,9 @@ def _load_logging_config(log_config_path: str) -> None:
|
|||
if not log_config:
|
||||
logging.warning("Loaded a blank logging config?")
|
||||
|
||||
# If the old structured logging configuration is being used, convert it to
|
||||
# the new style configuration.
|
||||
# If the old structured logging configuration is being used, raise an error.
|
||||
if "structured" in log_config and log_config.get("structured"):
|
||||
log_config = setup_structured_logging(log_config)
|
||||
raise ConfigError(STRUCTURED_ERROR)
|
||||
|
||||
logging.config.dictConfig(log_config)
|
||||
|
||||
|
|
|
@ -1,163 +0,0 @@
|
|||
# Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import os.path
|
||||
from typing import Any, Dict, Generator, Optional, Tuple
|
||||
|
||||
from constantly import NamedConstant, Names
|
||||
|
||||
from synapse.config._base import ConfigError
|
||||
|
||||
|
||||
class DrainType(Names):
|
||||
CONSOLE = NamedConstant()
|
||||
CONSOLE_JSON = NamedConstant()
|
||||
CONSOLE_JSON_TERSE = NamedConstant()
|
||||
FILE = NamedConstant()
|
||||
FILE_JSON = NamedConstant()
|
||||
NETWORK_JSON_TERSE = NamedConstant()
|
||||
|
||||
|
||||
DEFAULT_LOGGERS = {"synapse": {"level": "info"}}
|
||||
|
||||
|
||||
def parse_drain_configs(
|
||||
drains: dict,
|
||||
) -> Generator[Tuple[str, Dict[str, Any]], None, None]:
|
||||
"""
|
||||
Parse the drain configurations.
|
||||
|
||||
Args:
|
||||
drains (dict): A list of drain configurations.
|
||||
|
||||
Yields:
|
||||
dict instances representing a logging handler.
|
||||
|
||||
Raises:
|
||||
ConfigError: If any of the drain configuration items are invalid.
|
||||
"""
|
||||
|
||||
for name, config in drains.items():
|
||||
if "type" not in config:
|
||||
raise ConfigError("Logging drains require a 'type' key.")
|
||||
|
||||
try:
|
||||
logging_type = DrainType.lookupByName(config["type"].upper())
|
||||
except ValueError:
|
||||
raise ConfigError(
|
||||
"%s is not a known logging drain type." % (config["type"],)
|
||||
)
|
||||
|
||||
# Either use the default formatter or the tersejson one.
|
||||
if logging_type in (
|
||||
DrainType.CONSOLE_JSON,
|
||||
DrainType.FILE_JSON,
|
||||
):
|
||||
formatter: Optional[str] = "json"
|
||||
elif logging_type in (
|
||||
DrainType.CONSOLE_JSON_TERSE,
|
||||
DrainType.NETWORK_JSON_TERSE,
|
||||
):
|
||||
formatter = "tersejson"
|
||||
else:
|
||||
# A formatter of None implies using the default formatter.
|
||||
formatter = None
|
||||
|
||||
if logging_type in [
|
||||
DrainType.CONSOLE,
|
||||
DrainType.CONSOLE_JSON,
|
||||
DrainType.CONSOLE_JSON_TERSE,
|
||||
]:
|
||||
location = config.get("location")
|
||||
if location is None or location not in ["stdout", "stderr"]:
|
||||
raise ConfigError(
|
||||
(
|
||||
"The %s drain needs the 'location' key set to "
|
||||
"either 'stdout' or 'stderr'."
|
||||
)
|
||||
% (logging_type,)
|
||||
)
|
||||
|
||||
yield name, {
|
||||
"class": "logging.StreamHandler",
|
||||
"formatter": formatter,
|
||||
"stream": "ext://sys." + location,
|
||||
}
|
||||
|
||||
elif logging_type in [DrainType.FILE, DrainType.FILE_JSON]:
|
||||
if "location" not in config:
|
||||
raise ConfigError(
|
||||
"The %s drain needs the 'location' key set." % (logging_type,)
|
||||
)
|
||||
|
||||
location = config.get("location")
|
||||
if os.path.abspath(location) != location:
|
||||
raise ConfigError(
|
||||
"File paths need to be absolute, '%s' is a relative path"
|
||||
% (location,)
|
||||
)
|
||||
|
||||
yield name, {
|
||||
"class": "logging.FileHandler",
|
||||
"formatter": formatter,
|
||||
"filename": location,
|
||||
}
|
||||
|
||||
elif logging_type in [DrainType.NETWORK_JSON_TERSE]:
|
||||
host = config.get("host")
|
||||
port = config.get("port")
|
||||
maximum_buffer = config.get("maximum_buffer", 1000)
|
||||
|
||||
yield name, {
|
||||
"class": "synapse.logging.RemoteHandler",
|
||||
"formatter": formatter,
|
||||
"host": host,
|
||||
"port": port,
|
||||
"maximum_buffer": maximum_buffer,
|
||||
}
|
||||
|
||||
else:
|
||||
raise ConfigError(
|
||||
"The %s drain type is currently not implemented."
|
||||
% (config["type"].upper(),)
|
||||
)
|
||||
|
||||
|
||||
def setup_structured_logging(
|
||||
log_config: dict,
|
||||
) -> dict:
|
||||
"""
|
||||
Convert a legacy structured logging configuration (from Synapse < v1.23.0)
|
||||
to one compatible with the new standard library handlers.
|
||||
"""
|
||||
if "drains" not in log_config:
|
||||
raise ConfigError("The logging configuration requires a list of drains.")
|
||||
|
||||
new_config = {
|
||||
"version": 1,
|
||||
"formatters": {
|
||||
"json": {"class": "synapse.logging.JsonFormatter"},
|
||||
"tersejson": {"class": "synapse.logging.TerseJsonFormatter"},
|
||||
},
|
||||
"handlers": {},
|
||||
"loggers": log_config.get("loggers", DEFAULT_LOGGERS),
|
||||
"root": {"handlers": []},
|
||||
}
|
||||
|
||||
for handler_name, handler in parse_drain_configs(log_config["drains"]):
|
||||
new_config["handlers"][handler_name] = handler
|
||||
|
||||
# Add each handler to the root logger.
|
||||
new_config["root"]["handlers"].append(handler_name)
|
||||
|
||||
return new_config
|
Loading…
Reference in New Issue