Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions swanlab/data/run/exp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import ujson
import os
import math
from datetime import datetime
from .db import (
Tag,
Namespace,
Expand Down Expand Up @@ -93,7 +94,9 @@ def add(self, key: str, data: DataType, step: int = None):
if not tag_obj.is_chart_valid:
return swanlog.warning(f"Chart {tag} has been marked as error, ignored.")
# 添加tag信息
tag_obj.add(data, step)
step = tag_obj.add(data, step)
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
swanlog.log(f"{timestamp} step:{step} tag:{tag} value:{str(data)}")


class SwanLabTag:
Expand Down Expand Up @@ -171,7 +174,12 @@ def add(self, data: DataType, step: int = None):
对于整型和浮点型,还存在极大和极小值的问题
目前的策略是让python解释器自己处理,在前端完成数据的格式化展示
"""
data = self.try_convert_after_add_chart(data, step)
try:
data = self.try_convert_after_add_chart(data, step)
except ValueError:
return swanlog.warning(
f"Data {data} on tag {self.tag} cannot be converted, SwanLab will ignore it, but the chart still exists."
)
is_nan = self.__is_nan(data)
if not is_nan:
# 如果数据比之前的数据小,则更新最小值,否则不更新
Expand Down Expand Up @@ -200,6 +208,8 @@ def add(self, data: DataType, step: int = None):
with get_a_lock(os.path.join(self.save_path, "_summary.json"), "w+") as f:
ujson.dump(self._summary, f, ensure_ascii=False)

return step

@property
def save_path(self):
"""获取当前tag的保存路径
Expand Down
3 changes: 2 additions & 1 deletion swanlab/data/run/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ def __init__(
config: dict = None,
log_level: str = None,
suffix: str = None,
loggings: bool = False,
):
"""
Initializing the SwanLabRun class involves configuring the settings and initiating other logging processes.
Expand Down Expand Up @@ -351,7 +352,7 @@ def __init__(
self.__settings = SwanDataSettings(run_id=self.__run_id)
# ---------------------------------- 初始化日志记录器 ----------------------------------
# output、console_dir等内容不依赖于实验名称的设置
register(self.__settings.output_path, self.__settings.console_dir)
register(self.__settings.output_path, self.__settings.console_dir, enable_logging=loggings)
# 初始化日志等级
level = self.__check_log_level(log_level)
swanlog.setLevel(level)
Expand Down
10 changes: 8 additions & 2 deletions swanlab/data/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def init(
logdir: str = None,
suffix: str = "timestamp",
log_level: str = None,
logggings: bool = False,
) -> SwanLabRun:
"""
Start a new run to track and log.
Expand Down Expand Up @@ -108,6 +109,7 @@ def init(
config=config,
log_level=log_level,
suffix=suffix,
loggings=logggings,
)
# 注册异常处理函数
sys.excepthook = __except_handler
Expand All @@ -122,7 +124,7 @@ def init(
return run


def log(data: Dict[str, DataType], step: int = None):
def log(data: Dict[str, DataType], step: int = None, loggings: bool = None):
"""
Log a row of data to the current run.

Expand All @@ -140,7 +142,11 @@ def log(data: Dict[str, DataType], step: int = None):
raise RuntimeError("You must call swanlab.data.init() before using log()")
if inited and run is None:
return swanlog.error("After calling finish(), you can no longer log data to the current experiment")
return run.log(data, step)

swanlog.set_temporary_logging(loggings)
l = run.log(data, step)
swanlog.reset_temporary_logging()
return l


def finish():
Expand Down
13 changes: 11 additions & 2 deletions swanlab/log/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
swanlog: Optional["SwanLog"] = SwanLog("SwanLab")


def register(output_path: str = None, console_path: str = None, log_level: str = None) -> SwanLog:
def register(
output_path: str = None,
console_path: str = None,
log_level: str = None,
enable_logging: bool = False,
) -> SwanLog:
"""注册日志模块

Parameters
Expand All @@ -22,11 +27,15 @@ def register(output_path: str = None, console_path: str = None, log_level: str =
输出路径
use_console_log : str
是否记录控制台打印信息
log_level : str
日志等级
enable_logging : bool
是否启用日志

Returns
-------
SwanLog
初始化后的swanlog对象
"""
swanlog.init(path=output_path, console_path=console_path, level=log_level)
swanlog.init(path=output_path, console_path=console_path, level=log_level, enable_logging=enable_logging)
return swanlog
56 changes: 56 additions & 0 deletions swanlab/log/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def __init__(self, fmt=None, datefmt=None, style="%", handle=None):
logging.WARNING: self.yellow,
logging.ERROR: self.red,
logging.CRITICAL: self.bold_red,
COLLECT_LEVEL: self.green,
}

def bold_red(self, s: str) -> str:
Expand Down Expand Up @@ -78,6 +79,7 @@ def __get_colored_str(self, levelno, message):
message : string
需要装载的颜色
"""

return self.__color_map.get(levelno)(message)

def format(self, record):
Expand Down Expand Up @@ -117,6 +119,9 @@ def emit(self, record):
super().emit(record)


COLLECT_LEVEL = 60


class SwanLog(Logsys):
# 日志系统支持的输出等级
__levels = {
Expand All @@ -127,8 +132,21 @@ class SwanLog(Logsys):
"critical": logging.CRITICAL,
}

# 是否打印收集信息
__logging = False
# 是否临时允许打印
__temp_logging = None
# 自定义等级
__LOG_LEVEL = {
"value": COLLECT_LEVEL,
"name": "COLLECT",
}

def __init__(self, name=__name__, level="debug"):
super()
# 自定义log级别
logging.addLevelName(self.__LOG_LEVEL["value"], self.__LOG_LEVEL["name"])
# 设置日志器
self.logger = logging.getLogger(name)
self.logger.setLevel(self._getLevel(level))
self.__consoler: SwanConsoler = None
Expand All @@ -140,6 +158,7 @@ def init(
console_level=None,
file_level=None,
console_path=None,
enable_logging=False,
):
"""初始化内部打印器
初始化的顺序最好别变,下面的一些设置方法没有使用查找式获取处理器,而是直接用索引获取的
Expand All @@ -157,8 +176,12 @@ def init(
文件日志级别,高于或等于该级别即记录到文件
console_path: str, optional
控制台日志文件路径,如果提供,则会将控制台日志记录到文件,否则不记录
enable_logging: bool, optional
是否在全局允许打印, 默认为 False
"""

# 保存设置
self.__logging = enable_logging
# 初始化控制台记录器
if self.__consoler is None and console_path:
self.debug("init consoler")
Expand Down Expand Up @@ -256,6 +279,19 @@ def setCollectionLevel(self, level):
"""
self.__consoler.setLevel(level)

def set_temporary_logging(self, temp_logging: bool):
"""设置临时打印权限

Parameters
----------
temp_logging : bool
"""
self.__temp_logging = temp_logging

def reset_temporary_logging(self):
"""重置临时打印权限"""
self.__temp_logging = None

def getCollectionLevel(self):
"""
获取日志收集级别。
Expand Down Expand Up @@ -325,6 +361,26 @@ def error(self, message):
def critical(self, message):
self.logger.critical(message)

@__concat_messages
def log(self, message):
"""全局自定义信息打印,级别最高
临时打印,为 None 的时候无效
1. 临时凭证为 true,通过
2. 未设临时凭证,且全局为true,通过
"""

if self.__temp_logging is True:
# 临时凭证通过
pass
elif self.__temp_logging is None and self.__logging:
# 临时凭证没设置,且全局设置通过,可以打印
pass
else:
# 别的情况都返回
return

self.logger.log(self.__LOG_LEVEL["value"], message)

def reset_console(self):
"""重置控制台记录器"""
self.__consoler.reset()
Expand Down
12 changes: 4 additions & 8 deletions test/create_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@
import time

swanlab.init(
log_level="debug",
log_level="info",
config={
"test": 1,
"debug": 1,
"verbose": 1,
},
logggings=True,
)

for i in range(100):
swanlab.log({"lllloss": "hahahah"})
# time.sleep(0.1)

for i in range(300):
swanlab.log({"acc": "nan"})
# time.sleep(0.1)
for i in range(10):
swanlab.log({"acc": i, "loss": "123"})