Remove emojis from logging statements
This commit is contained in:
parent
ba562168aa
commit
4f3632bc6b
|
@ -149,7 +149,7 @@ class BaseAction(ABC):
|
||||||
if self.inject_last_result and self.shared_context:
|
if self.inject_last_result and self.shared_context:
|
||||||
key = self.inject_into
|
key = self.inject_into
|
||||||
if key in kwargs:
|
if key in kwargs:
|
||||||
logger.warning("[%s] ⚠️ Overriding '%s' with last_result", self.name, key)
|
logger.warning("[%s] Overriding '%s' with last_result", self.name, key)
|
||||||
kwargs = dict(kwargs)
|
kwargs = dict(kwargs)
|
||||||
kwargs[key] = self.shared_context.last_result()
|
kwargs[key] = self.shared_context.last_result()
|
||||||
return kwargs
|
return kwargs
|
||||||
|
@ -278,7 +278,7 @@ class Action(BaseAction):
|
||||||
context.exception = error
|
context.exception = error
|
||||||
await self.hooks.trigger(HookType.ON_ERROR, context)
|
await self.hooks.trigger(HookType.ON_ERROR, context)
|
||||||
if context.result is not None:
|
if context.result is not None:
|
||||||
logger.info("[%s] ✅ Recovered: %s", self.name, self.name)
|
logger.info("[%s] Recovered: %s", self.name, self.name)
|
||||||
return context.result
|
return context.result
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
|
@ -518,7 +518,7 @@ class ChainedAction(BaseAction, ActionListMixin):
|
||||||
for index, action in enumerate(self.actions):
|
for index, action in enumerate(self.actions):
|
||||||
if action._skip_in_chain:
|
if action._skip_in_chain:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"[%s] ⚠️ Skipping consumed action '%s'", self.name, action.name
|
"[%s] Skipping consumed action '%s'", self.name, action.name
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
shared_context.current_index = index
|
shared_context.current_index = index
|
||||||
|
@ -530,7 +530,7 @@ class ChainedAction(BaseAction, ActionListMixin):
|
||||||
self.actions[index + 1], FallbackAction
|
self.actions[index + 1], FallbackAction
|
||||||
):
|
):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"[%s] ⚠️ Fallback triggered: %s, recovering with fallback "
|
"[%s] Fallback triggered: %s, recovering with fallback "
|
||||||
"'%s'.",
|
"'%s'.",
|
||||||
self.name,
|
self.name,
|
||||||
error,
|
error,
|
||||||
|
@ -585,10 +585,10 @@ class ChainedAction(BaseAction, ActionListMixin):
|
||||||
rollback = getattr(action, "rollback", None)
|
rollback = getattr(action, "rollback", None)
|
||||||
if rollback:
|
if rollback:
|
||||||
try:
|
try:
|
||||||
logger.warning("[%s] ↩️ Rolling back...", action.name)
|
logger.warning("[%s] Rolling back...", action.name)
|
||||||
await action.rollback(*args, **kwargs)
|
await action.rollback(*args, **kwargs)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
logger.error("[%s] ⚠️ Rollback failed: %s", action.name, error)
|
logger.error("[%s] Rollback failed: %s", action.name, error)
|
||||||
|
|
||||||
def register_hooks_recursively(self, hook_type: HookType, hook: Hook):
|
def register_hooks_recursively(self, hook_type: HookType, hook: Hook):
|
||||||
"""Register a hook for all actions and sub-actions."""
|
"""Register a hook for all actions and sub-actions."""
|
||||||
|
|
|
@ -28,7 +28,7 @@ async def close_shared_http_session(context: ExecutionContext) -> None:
|
||||||
if session and should_close:
|
if session and should_close:
|
||||||
await session.close()
|
await session.close()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
logger.warning("⚠️ Error closing shared HTTP session: %s", error)
|
logger.warning("Error closing shared HTTP session: %s", error)
|
||||||
|
|
||||||
|
|
||||||
class HTTPAction(Action):
|
class HTTPAction(Action):
|
||||||
|
|
|
@ -119,7 +119,7 @@ class SelectFileAction(BaseAction):
|
||||||
description=file.name, value=value, style=self.style
|
description=file.name, value=value, style=self.style
|
||||||
)
|
)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
logger.warning("[ERROR] Failed to parse %s: %s", file.name, error)
|
logger.error("Failed to parse %s: %s", file.name, error)
|
||||||
return options
|
return options
|
||||||
|
|
||||||
def _find_cancel_key(self, options) -> str:
|
def _find_cancel_key(self, options) -> str:
|
||||||
|
|
|
@ -245,7 +245,7 @@ class Command(BaseModel):
|
||||||
if self.preview_before_confirm:
|
if self.preview_before_confirm:
|
||||||
await self.preview()
|
await self.preview()
|
||||||
if not await confirm_async(self.confirmation_prompt):
|
if not await confirm_async(self.confirmation_prompt):
|
||||||
logger.info("[Command:%s] ❌ Cancelled by user.", self.key)
|
logger.info("[Command:%s] Cancelled by user.", self.key)
|
||||||
raise CancelSignal(f"[Command:{self.key}] Cancelled by confirmation.")
|
raise CancelSignal(f"[Command:{self.key}] Cancelled by confirmation.")
|
||||||
|
|
||||||
context.start_timer()
|
context.start_timer()
|
||||||
|
|
|
@ -140,9 +140,9 @@ class ExecutionContext(BaseModel):
|
||||||
message.append(f"Duration: {summary['duration']:.3f}s | ")
|
message.append(f"Duration: {summary['duration']:.3f}s | ")
|
||||||
|
|
||||||
if summary["exception"]:
|
if summary["exception"]:
|
||||||
message.append(f"❌ Exception: {summary['exception']}")
|
message.append(f"Exception: {summary['exception']}")
|
||||||
else:
|
else:
|
||||||
message.append(f"✅ Result: {summary['result']}")
|
message.append(f"Result: {summary['result']}")
|
||||||
(logger or self.console.print)("".join(message))
|
(logger or self.console.print)("".join(message))
|
||||||
|
|
||||||
def to_log_line(self) -> str:
|
def to_log_line(self) -> str:
|
||||||
|
|
|
@ -10,7 +10,7 @@ def log_before(context: ExecutionContext):
|
||||||
args = ", ".join(map(repr, context.args))
|
args = ", ".join(map(repr, context.args))
|
||||||
kwargs = ", ".join(f"{k}={v!r}" for k, v in context.kwargs.items())
|
kwargs = ", ".join(f"{k}={v!r}" for k, v in context.kwargs.items())
|
||||||
signature = ", ".join(filter(None, [args, kwargs]))
|
signature = ", ".join(filter(None, [args, kwargs]))
|
||||||
logger.info("[%s] 🚀 Starting → %s(%s)", context.name, context.action, signature)
|
logger.info("[%s] Starting → %s(%s)", context.name, context.action, signature)
|
||||||
|
|
||||||
|
|
||||||
def log_success(context: ExecutionContext):
|
def log_success(context: ExecutionContext):
|
||||||
|
@ -18,18 +18,18 @@ def log_success(context: ExecutionContext):
|
||||||
result_str = repr(context.result)
|
result_str = repr(context.result)
|
||||||
if len(result_str) > 100:
|
if len(result_str) > 100:
|
||||||
result_str = f"{result_str[:100]} ..."
|
result_str = f"{result_str[:100]} ..."
|
||||||
logger.debug("[%s] ✅ Success → Result: %s", context.name, result_str)
|
logger.debug("[%s] Success → Result: %s", context.name, result_str)
|
||||||
|
|
||||||
|
|
||||||
def log_after(context: ExecutionContext):
|
def log_after(context: ExecutionContext):
|
||||||
"""Log the completion of an action, regardless of success or failure."""
|
"""Log the completion of an action, regardless of success or failure."""
|
||||||
logger.debug("[%s] ⏱️ Finished in %.3fs", context.name, context.duration)
|
logger.debug("[%s] Finished in %.3fs", context.name, context.duration)
|
||||||
|
|
||||||
|
|
||||||
def log_error(context: ExecutionContext):
|
def log_error(context: ExecutionContext):
|
||||||
"""Log an error that occurred during the action."""
|
"""Log an error that occurred during the action."""
|
||||||
logger.error(
|
logger.error(
|
||||||
"[%s] ❌ Error (%s): %s",
|
"[%s] Error (%s): %s",
|
||||||
context.name,
|
context.name,
|
||||||
type(context.exception).__name__,
|
type(context.exception).__name__,
|
||||||
context.exception,
|
context.exception,
|
||||||
|
|
|
@ -852,7 +852,7 @@ class Falyx:
|
||||||
self.last_run_command = selected_command
|
self.last_run_command = selected_command
|
||||||
|
|
||||||
if selected_command == self.exit_command:
|
if selected_command == self.exit_command:
|
||||||
logger.info("🔙 Back selected: exiting %s", self.get_title())
|
logger.info("Back selected: exiting %s", self.get_title())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
context = self._create_context(selected_command)
|
context = self._create_context(selected_command)
|
||||||
|
@ -895,7 +895,7 @@ class Falyx:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"[run_key] 🚀 Executing: %s — %s",
|
"[run_key] Executing: %s — %s",
|
||||||
selected_command.key,
|
selected_command.key,
|
||||||
selected_command.description,
|
selected_command.description,
|
||||||
)
|
)
|
||||||
|
@ -908,10 +908,10 @@ class Falyx:
|
||||||
context.result = result
|
context.result = result
|
||||||
|
|
||||||
await self.hooks.trigger(HookType.ON_SUCCESS, context)
|
await self.hooks.trigger(HookType.ON_SUCCESS, context)
|
||||||
logger.info("[run_key] ✅ '%s' complete.", selected_command.description)
|
logger.info("[run_key] '%s' complete.", selected_command.description)
|
||||||
except (KeyboardInterrupt, EOFError) as error:
|
except (KeyboardInterrupt, EOFError) as error:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"[run_key] ⚠️ Interrupted by user: %s", selected_command.description
|
"[run_key] Interrupted by user: %s", selected_command.description
|
||||||
)
|
)
|
||||||
raise FalyxError(
|
raise FalyxError(
|
||||||
f"[run_key] ⚠️ '{selected_command.description}' interrupted by user."
|
f"[run_key] ⚠️ '{selected_command.description}' interrupted by user."
|
||||||
|
@ -920,7 +920,7 @@ class Falyx:
|
||||||
context.exception = error
|
context.exception = error
|
||||||
await self.hooks.trigger(HookType.ON_ERROR, context)
|
await self.hooks.trigger(HookType.ON_ERROR, context)
|
||||||
logger.error(
|
logger.error(
|
||||||
"[run_key] ❌ Failed: %s — %s: %s",
|
"[run_key] Failed: %s — %s: %s",
|
||||||
selected_command.description,
|
selected_command.description,
|
||||||
type(error).__name__,
|
type(error).__name__,
|
||||||
error,
|
error,
|
||||||
|
@ -1024,7 +1024,7 @@ class Falyx:
|
||||||
logging.getLogger("falyx").setLevel(logging.DEBUG)
|
logging.getLogger("falyx").setLevel(logging.DEBUG)
|
||||||
|
|
||||||
if self.cli_args.debug_hooks:
|
if self.cli_args.debug_hooks:
|
||||||
logger.debug("✅ Enabling global debug hooks for all commands")
|
logger.debug("Enabling global debug hooks for all commands")
|
||||||
self.register_all_with_debug_hooks()
|
self.register_all_with_debug_hooks()
|
||||||
|
|
||||||
if self.cli_args.command == "list":
|
if self.cli_args.command == "list":
|
||||||
|
|
|
@ -65,7 +65,7 @@ class HookManager:
|
||||||
hook(context)
|
hook(context)
|
||||||
except Exception as hook_error:
|
except Exception as hook_error:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"⚠️ Hook '%s' raised an exception during '%s' for '%s': %s",
|
"[Hook:%s] raised an exception during '%s' for '%s': %s",
|
||||||
hook.__name__,
|
hook.__name__,
|
||||||
hook_type,
|
hook_type,
|
||||||
context.name,
|
context.name,
|
||||||
|
|
|
@ -56,10 +56,10 @@ class CircuitBreaker:
|
||||||
if self.open_until:
|
if self.open_until:
|
||||||
if time.time() < self.open_until:
|
if time.time() < self.open_until:
|
||||||
raise CircuitBreakerOpen(
|
raise CircuitBreakerOpen(
|
||||||
f"🔴 Circuit open for '{name}' until {time.ctime(self.open_until)}."
|
f"Circuit open for '{name}' until {time.ctime(self.open_until)}."
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.info("🟢 Circuit closed again for '%s'.")
|
logger.info("Circuit closed again for '%s'.")
|
||||||
self.failures = 0
|
self.failures = 0
|
||||||
self.open_until = None
|
self.open_until = None
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class CircuitBreaker:
|
||||||
name = context.name
|
name = context.name
|
||||||
self.failures += 1
|
self.failures += 1
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"⚠️ CircuitBreaker: '%s' failure %s/%s.",
|
"CircuitBreaker: '%s' failure %s/%s.",
|
||||||
name,
|
name,
|
||||||
self.failures,
|
self.failures,
|
||||||
self.max_failures,
|
self.max_failures,
|
||||||
|
@ -75,7 +75,7 @@ class CircuitBreaker:
|
||||||
if self.failures >= self.max_failures:
|
if self.failures >= self.max_failures:
|
||||||
self.open_until = time.time() + self.reset_timeout
|
self.open_until = time.time() + self.reset_timeout
|
||||||
logger.error(
|
logger.error(
|
||||||
"🔴 Circuit opened for '%s' until %s.", name, time.ctime(self.open_until)
|
"Circuit opened for '%s' until %s.", name, time.ctime(self.open_until)
|
||||||
)
|
)
|
||||||
|
|
||||||
def after_hook(self, _: ExecutionContext):
|
def after_hook(self, _: ExecutionContext):
|
||||||
|
@ -87,4 +87,4 @@ class CircuitBreaker:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.failures = 0
|
self.failures = 0
|
||||||
self.open_until = None
|
self.open_until = None
|
||||||
logger.info("🔄 Circuit reset.")
|
logger.info("Circuit reset.")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from falyx import logger
|
from falyx.logger import logger
|
||||||
from falyx.parsers.signature import infer_args_from_func
|
from falyx.parsers.signature import infer_args_from_func
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ class RetryHandler:
|
||||||
self.policy.delay = delay
|
self.policy.delay = delay
|
||||||
self.policy.backoff = backoff
|
self.policy.backoff = backoff
|
||||||
self.policy.jitter = jitter
|
self.policy.jitter = jitter
|
||||||
logger.info("🔄 Retry policy enabled: %s", self.policy)
|
logger.info("Retry policy enabled: %s", self.policy)
|
||||||
|
|
||||||
async def retry_on_error(self, context: ExecutionContext) -> None:
|
async def retry_on_error(self, context: ExecutionContext) -> None:
|
||||||
from falyx.action import Action
|
from falyx.action import Action
|
||||||
|
@ -67,21 +67,21 @@ class RetryHandler:
|
||||||
last_error = error
|
last_error = error
|
||||||
|
|
||||||
if not target:
|
if not target:
|
||||||
logger.warning("[%s] ⚠️ No action target. Cannot retry.", name)
|
logger.warning("[%s] No action target. Cannot retry.", name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not isinstance(target, Action):
|
if not isinstance(target, Action):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"[%s] ❌ RetryHandler only supports only supports Action objects.", name
|
"[%s] RetryHandler only supports only supports Action objects.", name
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not getattr(target, "is_retryable", False):
|
if not getattr(target, "is_retryable", False):
|
||||||
logger.warning("[%s] ❌ Not retryable.", name)
|
logger.warning("[%s] Not retryable.", name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not self.policy.enabled:
|
if not self.policy.enabled:
|
||||||
logger.warning("[%s] ❌ Retry policy is disabled.", name)
|
logger.warning("[%s] Retry policy is disabled.", name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
while retries_done < self.policy.max_retries:
|
while retries_done < self.policy.max_retries:
|
||||||
|
@ -92,7 +92,7 @@ class RetryHandler:
|
||||||
sleep_delay += random.uniform(-self.policy.jitter, self.policy.jitter)
|
sleep_delay += random.uniform(-self.policy.jitter, self.policy.jitter)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"[%s] 🔄 Retrying (%s/%s) in %ss due to '%s'...",
|
"[%s] Retrying (%s/%s) in %ss due to '%s'...",
|
||||||
name,
|
name,
|
||||||
retries_done,
|
retries_done,
|
||||||
self.policy.max_retries,
|
self.policy.max_retries,
|
||||||
|
@ -104,13 +104,13 @@ class RetryHandler:
|
||||||
result = await target.action(*context.args, **context.kwargs)
|
result = await target.action(*context.args, **context.kwargs)
|
||||||
context.result = result
|
context.result = result
|
||||||
context.exception = None
|
context.exception = None
|
||||||
logger.info("[%s] ✅ Retry succeeded on attempt %s.", name, retries_done)
|
logger.info("[%s] Retry succeeded on attempt %s.", name, retries_done)
|
||||||
return None
|
return None
|
||||||
except Exception as retry_error:
|
except Exception as retry_error:
|
||||||
last_error = retry_error
|
last_error = retry_error
|
||||||
current_delay *= self.policy.backoff
|
current_delay *= self.policy.backoff
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"[%s] ⚠️ Retry attempt %s/%s failed due to '%s'.",
|
"[%s] Retry attempt %s/%s failed due to '%s'.",
|
||||||
name,
|
name,
|
||||||
retries_done,
|
retries_done,
|
||||||
self.policy.max_retries,
|
self.policy.max_retries,
|
||||||
|
@ -118,4 +118,4 @@ class RetryHandler:
|
||||||
)
|
)
|
||||||
|
|
||||||
context.exception = last_error
|
context.exception = last_error
|
||||||
logger.error("[%s] ❌ All %s retries failed.", name, self.policy.max_retries)
|
logger.error("[%s] All %s retries failed.", name, self.policy.max_retries)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
__version__ = "0.1.35"
|
__version__ = "0.1.36"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "falyx"
|
name = "falyx"
|
||||||
version = "0.1.35"
|
version = "0.1.36"
|
||||||
description = "Reliable and introspectable async CLI action framework."
|
description = "Reliable and introspectable async CLI action framework."
|
||||||
authors = ["Roland Thomas Jr <roland@rtj.dev>"]
|
authors = ["Roland Thomas Jr <roland@rtj.dev>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
Loading…
Reference in New Issue