mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
allow logger to be reconfigured after startup
This commit is contained in:
parent
01f46d3c7d
commit
f2bb507ebb
@ -4,7 +4,6 @@ from inspect import signature
|
|||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
from invokeai.backend.util.logging import InvokeAILogger
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
|
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
|
||||||
@ -15,15 +14,19 @@ from fastapi_events.middleware import EventHandlerASGIMiddleware
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pydantic.schema import schema
|
from pydantic.schema import schema
|
||||||
|
|
||||||
|
#This should come early so that modules can log their initialization properly
|
||||||
|
from .services.config import InvokeAIAppConfig
|
||||||
|
from ..backend.util.logging import InvokeAILogger
|
||||||
|
app_config = InvokeAIAppConfig.get_config()
|
||||||
|
app_config.parse_args()
|
||||||
|
logger = InvokeAILogger.getLogger(config=app_config)
|
||||||
|
|
||||||
import invokeai.frontend.web as web_dir
|
import invokeai.frontend.web as web_dir
|
||||||
|
|
||||||
from .api.dependencies import ApiDependencies
|
from .api.dependencies import ApiDependencies
|
||||||
from .api.routers import sessions, models, images
|
from .api.routers import sessions, models, images
|
||||||
from .api.sockets import SocketIO
|
from .api.sockets import SocketIO
|
||||||
from .invocations.baseinvocation import BaseInvocation
|
from .invocations.baseinvocation import BaseInvocation
|
||||||
from .services.config import InvokeAIAppConfig
|
|
||||||
|
|
||||||
logger = InvokeAILogger.getLogger()
|
|
||||||
|
|
||||||
# Create the app
|
# Create the app
|
||||||
# TODO: create this all in a method so configuration/etc. can be passed in?
|
# TODO: create this all in a method so configuration/etc. can be passed in?
|
||||||
@ -41,11 +44,6 @@ app.add_middleware(
|
|||||||
|
|
||||||
socket_io = SocketIO(app)
|
socket_io = SocketIO(app)
|
||||||
|
|
||||||
# initialize config
|
|
||||||
# this is a module global
|
|
||||||
app_config = InvokeAIAppConfig.get_config()
|
|
||||||
app_config.parse_args()
|
|
||||||
|
|
||||||
# Add startup event to load dependencies
|
# Add startup event to load dependencies
|
||||||
@app.on_event("startup")
|
@app.on_event("startup")
|
||||||
async def startup_event():
|
async def startup_event():
|
||||||
|
@ -40,6 +40,7 @@ import invokeai.configs as configs
|
|||||||
from invokeai.app.services.config import (
|
from invokeai.app.services.config import (
|
||||||
InvokeAIAppConfig,
|
InvokeAIAppConfig,
|
||||||
)
|
)
|
||||||
|
from invokeai.backend.util.logging import InvokeAILogger
|
||||||
from invokeai.frontend.install.model_install import addModelsForm, process_and_execute
|
from invokeai.frontend.install.model_install import addModelsForm, process_and_execute
|
||||||
from invokeai.frontend.install.widgets import (
|
from invokeai.frontend.install.widgets import (
|
||||||
CenteredButtonPress,
|
CenteredButtonPress,
|
||||||
@ -80,6 +81,7 @@ INIT_FILE_PREAMBLE = """# InvokeAI initialization file
|
|||||||
# or renaming it and then running invokeai-configure again.
|
# or renaming it and then running invokeai-configure again.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
logger=None
|
||||||
|
|
||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
def postscript(errors: None):
|
def postscript(errors: None):
|
||||||
@ -824,6 +826,7 @@ def main():
|
|||||||
if opt.full_precision:
|
if opt.full_precision:
|
||||||
invoke_args.extend(['--precision','float32'])
|
invoke_args.extend(['--precision','float32'])
|
||||||
config.parse_args(invoke_args)
|
config.parse_args(invoke_args)
|
||||||
|
logger = InvokeAILogger().getLogger(config=config)
|
||||||
|
|
||||||
errors = set()
|
errors = set()
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Copyright (c) 2023 Lincoln D. Stein and The InvokeAI Development Team
|
# Copyright (c) 2023 Lincoln D. Stein and The InvokeAI Development Team
|
||||||
|
|
||||||
"""invokeai.util.logging
|
"""
|
||||||
|
invokeai.util.logging
|
||||||
|
|
||||||
Logging class for InvokeAI that produces console messages
|
Logging class for InvokeAI that produces console messages
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ from invokeai.backend.util.logging import InvokeAILogger
|
|||||||
logger = InvokeAILogger.getLogger(name='InvokeAI') // Initialization
|
logger = InvokeAILogger.getLogger(name='InvokeAI') // Initialization
|
||||||
(or)
|
(or)
|
||||||
logger = InvokeAILogger.getLogger(__name__) // To use the filename
|
logger = InvokeAILogger.getLogger(__name__) // To use the filename
|
||||||
|
logger.configure()
|
||||||
|
|
||||||
logger.critical('this is critical') // Critical Message
|
logger.critical('this is critical') // Critical Message
|
||||||
logger.error('this is an error') // Error Message
|
logger.error('this is an error') // Error Message
|
||||||
@ -28,6 +30,149 @@ Console messages:
|
|||||||
Alternate Method (in this case the logger name will be set to InvokeAI):
|
Alternate Method (in this case the logger name will be set to InvokeAI):
|
||||||
import invokeai.backend.util.logging as IAILogger
|
import invokeai.backend.util.logging as IAILogger
|
||||||
IAILogger.debug('this is a debugging message')
|
IAILogger.debug('this is a debugging message')
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The default configuration will print to stderr on the console. To add
|
||||||
|
additional logging handlers, call getLogger with an initialized InvokeAIAppConfig
|
||||||
|
object:
|
||||||
|
|
||||||
|
|
||||||
|
config = InvokeAIAppConfig.get_config()
|
||||||
|
config.parse_args()
|
||||||
|
logger = InvokeAILogger.getLogger(config=config)
|
||||||
|
|
||||||
|
### Three command-line options control logging:
|
||||||
|
|
||||||
|
`--log_handlers <handler1> <handler2> ...`
|
||||||
|
|
||||||
|
This option activates one or more log handlers. Options are "console", "file", "syslog" and "http". To specify more than one, separate them by spaces:
|
||||||
|
|
||||||
|
```
|
||||||
|
invokeai-web --log_handlers console syslog=/dev/log file=C:\\Users\\fred\\invokeai.log
|
||||||
|
```
|
||||||
|
|
||||||
|
The format of these options is described below.
|
||||||
|
|
||||||
|
### `--log_format {plain|color|legacy|syslog}`
|
||||||
|
|
||||||
|
This controls the format of log messages written to the console. Only the "console" log handler is currently affected by this setting.
|
||||||
|
|
||||||
|
* "plain" provides formatted messages like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
|
||||||
|
[2023-05-24 23:18:2[2023-05-24 23:18:50,352]::[InvokeAI]::DEBUG --> this is a debug message
|
||||||
|
[2023-05-24 23:18:50,352]::[InvokeAI]::INFO --> this is an informational messages
|
||||||
|
[2023-05-24 23:18:50,352]::[InvokeAI]::WARNING --> this is a warning
|
||||||
|
[2023-05-24 23:18:50,352]::[InvokeAI]::ERROR --> this is an error
|
||||||
|
[2023-05-24 23:18:50,352]::[InvokeAI]::CRITICAL --> this is a critical error
|
||||||
|
```
|
||||||
|
|
||||||
|
* "color" produces similar output, but the text will be color coded to indicate the severity of the message.
|
||||||
|
|
||||||
|
* "legacy" produces output similar to InvokeAI versions 2.3 and earlier:
|
||||||
|
|
||||||
|
```
|
||||||
|
### this is a critical error
|
||||||
|
*** this is an error
|
||||||
|
** this is a warning
|
||||||
|
>> this is an informational messages
|
||||||
|
| this is a debug message
|
||||||
|
```
|
||||||
|
|
||||||
|
* "syslog" produces messages suitable for syslog entries:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
InvokeAI [2691178] <CRITICAL> this is a critical error
|
||||||
|
InvokeAI [2691178] <ERROR> this is an error
|
||||||
|
InvokeAI [2691178] <WARNING> this is a warning
|
||||||
|
InvokeAI [2691178] <INFO> this is an informational messages
|
||||||
|
InvokeAI [2691178] <DEBUG> this is a debug message
|
||||||
|
```
|
||||||
|
|
||||||
|
(note that the date, time and hostname will be added by the syslog system)
|
||||||
|
|
||||||
|
### `--log_level {debug|info|warning|error|critical}`
|
||||||
|
|
||||||
|
Providing this command-line option will cause only messages at the specified level or above to be emitted.
|
||||||
|
|
||||||
|
## Console logging
|
||||||
|
|
||||||
|
When "console" is provided to `--log_handlers`, messages will be written to the command line window in which InvokeAI was launched. By default, the color formatter will be used unless overridden by `--log_format`.
|
||||||
|
|
||||||
|
## File logging
|
||||||
|
|
||||||
|
When "file" is provided to `--log_handlers`, entries will be written to the file indicated in the path argument. By default, the "plain" format will be used:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
invokeai-web --log_handlers file=/var/log/invokeai.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Syslog logging
|
||||||
|
|
||||||
|
When "syslog" is requested, entries will be sent to the syslog system. There are a variety of ways to control where the log message is sent:
|
||||||
|
|
||||||
|
* Send to the local machine using the `/dev/log` socket:
|
||||||
|
|
||||||
|
```
|
||||||
|
invokeai-web --log_handlers syslog=/dev/log
|
||||||
|
```
|
||||||
|
|
||||||
|
* Send to the local machine using a UDP message:
|
||||||
|
|
||||||
|
```
|
||||||
|
invokeai-web --log_handlers syslog=localhost
|
||||||
|
```
|
||||||
|
|
||||||
|
* Send to the local machine using a UDP message on a nonstandard port:
|
||||||
|
|
||||||
|
```
|
||||||
|
invokeai-web --log_handlers syslog=localhost:512
|
||||||
|
```
|
||||||
|
|
||||||
|
* Send to a remote machine named "loghost" on the local LAN using facility LOG_USER and UDP packets:
|
||||||
|
|
||||||
|
```
|
||||||
|
invokeai-web --log_handlers syslog=loghost,facility=LOG_USER,socktype=SOCK_DGRAM
|
||||||
|
```
|
||||||
|
|
||||||
|
This can be abbreviated `syslog=loghost`, as LOG_USER and SOCK_DGRAM are defaults.
|
||||||
|
|
||||||
|
* Send to a remote machine named "loghost" using the facility LOCAL0 and using a TCP socket:
|
||||||
|
|
||||||
|
```
|
||||||
|
invokeai-web --log_handlers syslog=loghost,facility=LOG_LOCAL0,socktype=SOCK_STREAM
|
||||||
|
```
|
||||||
|
|
||||||
|
If no arguments are specified (just a bare "syslog"), then the logging system will look for a UNIX socket named `/dev/log`, and if not found try to send a UDP message to `localhost`. The Macintosh OS used to support logging to a socket named `/var/run/syslog`, but this feature has since been disabled.
|
||||||
|
|
||||||
|
## Web logging
|
||||||
|
|
||||||
|
If you have access to a web server that is configured to log messages when a particular URL is requested, you can log using the "http" method:
|
||||||
|
|
||||||
|
```
|
||||||
|
invokeai-web --log_handlers http=http://my.server/path/to/logger,method=POST
|
||||||
|
```
|
||||||
|
|
||||||
|
The optional [,method=] part can be used to specify whether the URL accepts GET (default) or POST messages.
|
||||||
|
|
||||||
|
Currently password authentication and SSL are not supported.
|
||||||
|
|
||||||
|
## Using the configuration file
|
||||||
|
|
||||||
|
You can set and forget logging options by adding a "Logging" section to `invokeai.yaml`:
|
||||||
|
|
||||||
|
```
|
||||||
|
InvokeAI:
|
||||||
|
[... other settings...]
|
||||||
|
Logging:
|
||||||
|
log_handlers:
|
||||||
|
- console
|
||||||
|
- syslog=/dev/log
|
||||||
|
log_level: info
|
||||||
|
log_format: color
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
@ -180,16 +325,17 @@ class InvokeAILogger(object):
|
|||||||
loggers = dict()
|
loggers = dict()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def getLogger(cls, name: str = 'InvokeAI', config: InvokeAIAppConfig=None) -> logging.Logger:
|
def getLogger(cls,
|
||||||
if not config:
|
name: str = 'InvokeAI',
|
||||||
config = InvokeAIAppConfig()
|
config: InvokeAIAppConfig=InvokeAIAppConfig.get_config())->logging.Logger:
|
||||||
config.parse_args()
|
if name in cls.loggers:
|
||||||
|
logger = cls.loggers[name]
|
||||||
if name not in cls.loggers:
|
logger.handlers.clear()
|
||||||
|
else:
|
||||||
logger = logging.getLogger(name)
|
logger = logging.getLogger(name)
|
||||||
logger.setLevel(config.log_level.upper()) # yes, strings work here
|
logger.setLevel(config.log_level.upper()) # yes, strings work here
|
||||||
for ch in cls.getLoggers(config):
|
for ch in cls.getLoggers(config):
|
||||||
logger.addHandler(ch)
|
logger.addHandler(ch)
|
||||||
cls.loggers[name] = logger
|
cls.loggers[name] = logger
|
||||||
return cls.loggers[name]
|
return cls.loggers[name]
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import torch
|
|||||||
from npyscreen import widget
|
from npyscreen import widget
|
||||||
from omegaconf import OmegaConf
|
from omegaconf import OmegaConf
|
||||||
|
|
||||||
import invokeai.backend.util.logging as logger
|
from invokeai.backend.util.logging import InvokeAILogger
|
||||||
|
|
||||||
from invokeai.backend.install.model_install_backend import (
|
from invokeai.backend.install.model_install_backend import (
|
||||||
Dataset_path,
|
Dataset_path,
|
||||||
@ -939,6 +939,7 @@ def main():
|
|||||||
if opt.full_precision:
|
if opt.full_precision:
|
||||||
invoke_args.extend(['--precision','float32'])
|
invoke_args.extend(['--precision','float32'])
|
||||||
config.parse_args(invoke_args)
|
config.parse_args(invoke_args)
|
||||||
|
logger = InvokeAILogger().getLogger(config=config)
|
||||||
|
|
||||||
if not (config.root_dir / config.conf_path.parent).exists():
|
if not (config.root_dir / config.conf_path.parent).exists():
|
||||||
logger.info(
|
logger.info(
|
||||||
|
Loading…
Reference in New Issue
Block a user