Skip to content

Commit

Permalink
Merge pull request #1997 from DSD-DBS/custom-promtail-conf
Browse files Browse the repository at this point in the history
feat: Add custom promtail / logging configuration for tools
  • Loading branch information
MoritzWeber0 authored Nov 14, 2024
2 parents 3ff3651 + ec83007 commit eb29790
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 14 deletions.
32 changes: 18 additions & 14 deletions backend/capellacollab/sessions/hooks/log_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from capellacollab.config import config
from capellacollab.sessions import models as sessions_models
from capellacollab.sessions.operators import models as operators_models
from capellacollab.tools import models as tools_models
from capellacollab.users.workspaces import crud as users_workspaces_crud

from . import interface
Expand All @@ -23,10 +24,7 @@ def post_session_creation_hook(
self,
request: interface.PostSessionCreationHookRequest,
) -> interface.PostSessionCreationHookResult:
if (
not self._loki_enabled
or request.db_session.type == sessions_models.SessionType.READONLY
):
if not self._log_collection_enabled(request.db_session):
return interface.PostSessionCreationHookResult()

workspaces = users_workspaces_crud.get_workspaces_for_user(
Expand All @@ -40,7 +38,7 @@ def post_session_creation_hook(
data=self._promtail_configuration(
username=request.user.name,
session_type=request.db_session.type.value,
tool_name=request.db_session.tool.name,
tool=request.db_session.tool,
version_name=request.db_session.version.name,
),
)
Expand All @@ -62,7 +60,7 @@ def post_session_creation_hook(
operators_models.PersistentVolume(
name="workspace",
read_only=False,
container_path=pathlib.PurePosixPath("/var/log/promtail"),
container_path=pathlib.PurePosixPath("/workspace"),
volume_name=workspaces[0].pvc_name,
),
]
Expand All @@ -84,23 +82,29 @@ def pre_session_termination_hook(
self,
request: interface.PreSessionTerminationHookRequest,
) -> interface.PreSessionTerminationHookResult:
if (
not self._loki_enabled
or request.session.type == sessions_models.SessionType.READONLY
):
if not self._log_collection_enabled(request.session):
return interface.PostSessionCreationHookResult()

request.operator._delete_config_map(name=request.session.id)
request.operator._delete_pod(name=f"{request.session.id}-promtail")

return interface.PreSessionTerminationHookResult()

def _log_collection_enabled(
self, session: sessions_models.DatabaseSession
) -> bool:
return (
self._loki_enabled
and session.type == sessions_models.SessionType.PERSISTENT
and session.tool.config.monitoring.logging.enabled
)

@classmethod
def _promtail_configuration(
cls,
username: str,
session_type: str,
tool_name: str,
tool: tools_models.DatabaseTool,
version_name: str,
) -> dict:
cfg = config.k8s.promtail
Expand All @@ -121,7 +125,7 @@ def _promtail_configuration(
}
],
"positions": {
"filename": "/var/log/promtail/positions.yaml"
"filename": f"/workspace/.promtail/positions-tool-{tool.id}.yaml"
},
"scrape_configs": [
{
Expand All @@ -139,9 +143,9 @@ def _promtail_configuration(
"labels": {
"username": username,
"session_type": session_type,
"tool": tool_name,
"tool": tool.name,
"version": version_name,
"__path__": "/var/log/promtail/**/*.log",
"__path__": tool.config.monitoring.logging.path,
},
}
],
Expand Down
19 changes: 19 additions & 0 deletions backend/capellacollab/tools/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from sqlalchemy import orm

from capellacollab import core
from capellacollab.config import config
from capellacollab.core import database
from capellacollab.core import pydantic as core_pydantic
from capellacollab.core.database import decorator
Expand Down Expand Up @@ -246,11 +247,29 @@ class PrometheusConfiguration(core_pydantic.BaseModel):
path: str = pydantic.Field(default="/prometheus")


class LoggingConfiguration(core_pydantic.BaseModel):
"""Side-car container to push logs to Grafana Loki"""

enabled: bool = pydantic.Field(
default=config.k8s.promtail.loki_enabled,
description="If enabled, logs will be pushed to Grafana Loki.",
)

path: str = pydantic.Field(
default="/workspace/**/*.log",
description="Path to the log files, can be a glob string.",
)


class SessionMonitoring(core_pydantic.BaseModel):
prometheus: PrometheusConfiguration = pydantic.Field(
default=PrometheusConfiguration(),
description="Configuration for monitoring and garbage collection.",
)
logging: LoggingConfiguration = pydantic.Field(
default=LoggingConfiguration(),
description="Configuration for side-car logging container.",
)


class ToolModelProvisioning(core_pydantic.BaseModel):
Expand Down
14 changes: 14 additions & 0 deletions backend/capellacollab/tools/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@

import capellacollab.projects.toolmodels.crud as projects_models_crud
import capellacollab.settings.modelsources.t4c.instance.crud as settings_t4c_crud
from capellacollab.config import config
from capellacollab.core import database
from capellacollab.core import exceptions as core_exceptions
from capellacollab.core.authentication import injectables as auth_injectables
from capellacollab.core.logging import exceptions as logging_exceptions
from capellacollab.users import models as users_models

from . import crud, exceptions, injectables, models
Expand Down Expand Up @@ -66,6 +68,12 @@ def create_tool(
To use this route, the user role `administrator` is required.
"""

if (
body.config.monitoring.logging.enabled
and not config.k8s.promtail.loki_enabled
):
raise logging_exceptions.GrafanaLokiDisabled()

return crud.create_tool(db, body)


Expand All @@ -85,6 +93,12 @@ def update_tool(
tool: models.DatabaseTool = fastapi.Depends(injectables.get_existing_tool),
db: orm.Session = fastapi.Depends(database.get_db),
) -> models.DatabaseTool:
if (
body.config.monitoring.logging.enabled
and not config.k8s.promtail.loki_enabled
):
raise logging_exceptions.GrafanaLokiDisabled()

return crud.update_tool(db, tool, body)


Expand Down
2 changes: 2 additions & 0 deletions frontend/src/app/openapi/.openapi-generator/FILES

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions frontend/src/app/openapi/model/logging-configuration-input.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions frontend/src/app/openapi/model/logging-configuration-output.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions frontend/src/app/openapi/model/models.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions frontend/src/app/openapi/model/session-monitoring-input.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions frontend/src/app/openapi/model/session-monitoring-output.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions frontend/src/storybook/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ const defaultToolConfig: ToolSessionConfigurationOutput = {
prometheus: {
path: '/metrics',
},
logging: {
enabled: true,
path: '/workspace/*.log',
},
},
supported_project_types: ['general', 'training'],
};
Expand Down

0 comments on commit eb29790

Please sign in to comment.