如何降低Python应用中AppDynamics代理和代理的标准输出详细程度

0 投票
1 回答
59 浏览
提问于 2025-04-12 23:32

我正在把AppDynamics的Python代理集成到一个FastAPI项目中,用来监控,但在控制台输出的日志详细程度上遇到了一些问题。我用以下命令启动我的FastAPI应用,以便包含AppDynamics代理:

pyagent run -c appdynamics.cfg uvicorn my_app:app --reload

我的目标是减少AppDynamics代理和代理服务器输出到控制台的日志详细程度,这样可以让我的控制台输出更干净,专注于更重要的问题。

我的模块版本:

$ pip freeze | grep appdy
appdynamics==23.10.0.6327
appdynamics-bindeps-linux-x64==23.10.0
appdynamics-proxysupport-linux-x64==11.64.3

这是我的appdynamics.cfg配置文件的内容:

[agent]
app = my-app
tier = my-tier
node = teste-local-01

[controller]
host = my-controller.saas.appdynamics.com
port = 443
ssl = true
account = my-account
accesskey = my-key

[log]
level = warning
debugging = off

我尝试通过修改代理的log4j.xml文件,将日志级别设置为WARNING,以进一步降低日志详细程度。但这个修改并没有达到我预期的效果。我调整的log4j.xml文件位于:

/tmp/appd/lib/cp311-cp311-63ff661bc175896c1717899ca23edc8f5fa87629d9e3bcd02cf4303ea4836f9f/site-packages/appdynamics_bindeps/proxy/conf/logging/log4j.xml

以下是我对log4j.xml所做的调整:

    <appender class="com.singularity.util.org.apache.log4j.ConsoleAppender" name="ConsoleAppender">
        <layout class="com.singularity.util.org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ABSOLUTE} %5p [%t] %c{1} - %m%n" />
        </layout>
        <filter class="com.singularity.util.org.apache.log4j.varia.LevelRangeFilter">
            <param name="LevelMax" value="FATAL" />
            <param name="LevelMin" value="WARNING" />
        </filter>

尽管我做了这些努力,我仍然看到来自代理和代理服务器的大量日志。有没有人能提供一些建议,如何有效降低AppDynamics Python代理及其代理的控制台输出日志?如果能确保我对log4j.xml的修改能够正确应用,也非常感谢。

提前感谢你的帮助!

我想从控制台输出中去除的日志消息示例:

2024-03-23 11:15:28,409 [INFO] appdynamics.proxy.watchdog <22759>: Started watchdog with pid=22759
2024-03-23 11:15:28,409 [INFO] appdynamics.proxy.watchdog <22759>: Started watchdog with pid=22759
...
[AD Thread Pool-ProxyControlReq0] Sat Mar 23 11:15:51 BRT 2024[DEBUG]: JavaAgent - Setting AgentClassLoader as Context ClassLoader
[AD Thread Pool-ProxyControlReq0] Sat Mar 23 11:15:52 BRT 2024[INFO]: JavaAgent - Low Entropy Mode: Attempting to swap to non-blocking PRNG algorithm
[AD Thread Pool-ProxyControlReq0] Sat Mar 23 11:15:52 BRT 2024[INFO]: JavaAgent - UUIDPool size is 10
Agent conf directory set to [/home/wsl/.pyenv/versions/3.11.6/lib/python3.11/site-packages/appdynamics_bindeps/proxy/conf]
...
11:15:52,167  INFO [AD Thread Pool-ProxyControlReq0] BusinessTransactions - Starting BT Logs at Sat Mar 23 11:15:52 BRT 2024
11:15:52,168  INFO [AD Thread Pool-ProxyControlReq0] BusinessTransactions - ###########################################################
11:15:52,169  INFO [AD Thread Pool-ProxyControlReq0] BusinessTransactions - Using Proxy Version [Python Agent v23.10.0.6327 (proxy v23.10.0.35234) compatible with 4.5.0.21130 Python Version 3.11.6]
11:15:52,169  INFO [AD Thread Pool-ProxyControlReq0] JavaAgent - Logging set up for log4j2
...
11:15:52,965  INFO [AD Thread Pool-ProxyControlReq0] JDBCConfiguration - Setting normalizePreparedStatements to true
11:15:52,965  INFO [AD Thread Pool-ProxyControlReq0] CallGraphConfigHandler - Call Graph Config Changed  callgraph-granularity-in-ms  Value -null

1 个回答

0

我遇到了一种解决方法,这是AppDynamics的一位工作人员在他们的本地实验中非正式提出的。虽然这个方法并没有得到AppDynamics的官方支持,但在我的AppDynamics设置中,它确实有效地调整了Proxy和Watchdog组件的日志级别。我想分享一下具体步骤,但请谨慎操作,记住这不是官方的解决方案。

我建议只修改log4j2.xml文件,因为代理消息几乎占了99%的日志信息。

以下是步骤总结:

  • 代理日志级别:这个由log4j2.xml文件控制。你可以在appdynamics_bindeps模块中找到它。例如,在我的WSL设置中,它的位置是/home/wsl/.pyenv/versions/3.11.6/lib/python3.11/site-packages/appdynamics_bindeps/proxy/conf/logging/log4j2.xml。在Docker镜像python:3.9中,路径是/usr/local/lib/python3.9/site-packages/appdynamics_bindeps/proxy/conf/logging/log4j2.xml。在<Loggers>部分中,修改七个<AsyncLogger>的日志级别项为以下之一:debug, info, warn, error, 或 fatal

  • 看门狗日志级别:这个可以在appdynamics Python模块中的proxy.py文件中调整。例如,在我的WSL设置中,它的位置是/home/wsl/.pyenv/versions/3.11.6/lib/python3.11/site-packages/appdynamics/scripts/pyagent/commands/proxy.py。在Docker镜像python:3.9中,路径是/usr/local/lib/python3.9/site-packages/appdynamics/scripts/pyagent/commands/proxy.py。你需要在configure_proxy_logger和configure_watchdog_logger函数中硬编码日志级别,通过修改level变量来实现。

我的版本

$ pip freeze | grep appdynamics
appdynamics==24.2.0.6567
appdynamics-bindeps-linux-x64==24.2.0
appdynamics-proxysupport-linux-x64==11.68.3

原始文件

log4j2.xml

<Loggers>
    <!-- Modify each <AsyncLogger> level as needed -->
        <AsyncLogger name="com.singularity" level="info" additivity="false">
            <AppenderRef ref="Default"/>
            <AppenderRef ref="RESTAppender"/>
            <AppenderRef ref="Console"/>
        </AsyncLogger>
</Loggers>

proxy.py

def configure_proxy_logger(debug):
    logger = logging.getLogger('appdynamics.proxy')
    level = logging.DEBUG if debug else logging.INFO
    pass

def configure_watchdog_logger(debug):
    logger = logging.getLogger('appdynamics.proxy')
    level = logging.DEBUG if debug else logging.INFO
    pass

我用来创建环境变量到log4j2.xml和proxy.py的脚本

update_appdynamics_log_level.sh

#!/bin/sh

# Check if PYENV_ROOT is not set
if [ -z "$PYENV_ROOT" ]; then
    # If PYENV_ROOT is not set, then set it to the default value
    export PYENV_ROOT="/usr/local/lib"
    echo "PYENV_ROOT was not set. Setting it to default: $PYENV_ROOT"
else
    echo "PYENV_ROOT is already set to: $PYENV_ROOT"
fi

echo "=========================== log4j2 - appdynamics_bindeps module ========================="

# Find the appdynamics_bindeps directory
APP_APPD_BINDEPS_DIR=$(find "$PYENV_ROOT" -type d -name "appdynamics_bindeps" -print -quit)

if [ -z "$APP_APPD_BINDEPS_DIR" ]; then
  echo "Error: appdynamics_bindeps directory not found."
  exit 1
fi

echo "Found appdynamics_bindeps directory at $APP_APPD_BINDEPS_DIR"

# Find the log4j2.xml file within the appdynamics_bindeps directory
APP_LOG4J2_FILE=$(find "$APP_APPD_BINDEPS_DIR" -type f -name "log4j2.xml" -print -quit)

if [ -z "$APP_LOG4J2_FILE" ]; then
  echo "Error: log4j2.xml file not found within the appdynamics_bindeps directory."
  exit 1
fi

echo "Found log4j2.xml file at $APP_LOG4J2_FILE"

# Modify the log level in the log4j2.xml file
echo "Modifying log level in log4j2.xml file"
sed -i 's/level="info"/level="${env:APP_APPD_LOG4J2_LOG_LEVEL:-info}"/g' "$APP_LOG4J2_FILE"

echo "log4j2.xml file modified successfully."

echo "=========================== watchdog - appdynamics module ==============================="

# Find the appdynamics directory
APP_APPD_DIR=$(find "$PYENV_ROOT" -type d -name "appdynamics" -print -quit)

if [ -z "$APP_APPD_DIR" ]; then
  echo "Error: appdynamics directory not found."
  exit 1
fi

echo "Found appdynamics directory at $APP_APPD_DIR"

# Find the proxy.py file within the appdynamics directory
APP_PROXY_PY_FILE=$(find "$APP_APPD_DIR" -type f -name "proxy.py" -print -quit)

if [ -z "$APP_PROXY_PY_FILE" ]; then
  echo "Error: proxy.py file not found within the appdynamics directory."
  exit 1
fi

echo "Found proxy.py file at $APP_PROXY_PY_FILE"

# Modify the log level in the proxy.py file
echo "Modifying log level in proxy.py file"
sed -i 's/logging.DEBUG if debug else logging.INFO/os.getenv("APP_APPD_WATCHDOG_LOG_LEVEL", "info").upper()/g' "$APP_PROXY_PY_FILE"


echo "proxy.py file modified successfully."

Dockerfile

Dockerfile用于运行pyagent与FastAPI,并执行这个脚本

# Use a specific version of the python image
FROM python:3.9

# Set the working directory in the container
WORKDIR /app

# First, copy only the requirements file and install dependencies to leverage Docker cache
COPY requirements.txt ./
RUN python3 -m pip install --no-cache-dir -r requirements.txt

# Now copy the rest of the application to the container
COPY . .

# Make the update_appdynamics_log_level.sh executable and run it
RUN chmod +x update_appdynamics_log_level.sh && \
    ./update_appdynamics_log_level.sh 

# Set environment variables
ENV APP_APPD_LOG4J2_LOG_LEVEL="warn" \
    APP_APPD_WATCHDOG_LOG_LEVEL="warn"

EXPOSE 8000

# Command to run the FastAPI application with pyagent
CMD ["pyagent", "run", "uvicorn", "main:app", "--proxy-headers", "--host","0.0.0.0", "--port","8000"]

脚本修改的文件

log4j2.xml

<Loggers>
    <!-- Modify each <AsyncLogger> level as needed -->
        <AsyncLogger name="com.singularity" level="${env:APP_APPD_LOG4J2_LOG_LEVEL:-info}" additivity="false">
            <AppenderRef ref="Default"/>
            <AppenderRef ref="RESTAppender"/>
            <AppenderRef ref="Console"/>
        </AsyncLogger>
</Loggers>

proxy.py

def configure_proxy_logger(debug):
    logger = logging.getLogger('appdynamics.proxy')
    level = os.getenv("APP_APPD_WATCHDOG_LOG_LEVEL", "info").upper()
    pass

def configure_watchdog_logger(debug):
    logger = logging.getLogger('appdynamics.proxy')
    level = os.getenv("APP_APPD_WATCHDOG_LOG_LEVEL", "info").upper()
    pass

警告

请注意,这些路径和方法可能会根据你的AppDynamics版本和环境设置有所不同。在进行更改之前,请务必备份文件,并注意AppDynamics的更新可能会覆盖你的自定义设置。

希望这能帮到你!

撰写回答