Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

log-viewer-webui: Add server implementation for submitting IR extraction jobs and serving IR files; Don't copy unnecessary files when building component. #458

Merged
merged 56 commits into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
220aeb8
implement basic functions
wraymo Jun 21, 2024
b6dcb54
fix a bug
wraymo Jun 24, 2024
77cd631
fix a bug
wraymo Jun 24, 2024
8664a31
refactor a bit
wraymo Jun 24, 2024
b932901
add docstring
wraymo Jun 24, 2024
c13d39d
use 127.0.0.1 instead of localhost
wraymo Jun 24, 2024
f017d0b
remove example routes and test
wraymo Jun 24, 2024
4729971
Apply suggestions from code review
kirkrodrigues Jul 7, 2024
7859aba
Merge branch 'refs/heads/main' into log_viewer_server
junhaoliao Jul 11, 2024
15b7459
Add `.env.local` for debug env var overrides.
junhaoliao Jul 11, 2024
0c99ef1
Add .env.local to .gitignore for debug purposes.
junhaoliao Jul 11, 2024
f090aff
Remove .env.local from VCS.
junhaoliao Jul 11, 2024
7a892dc
Add extract-IR job and polling, rework routes and DB interaction.
junhaoliao Jul 16, 2024
eda691c
Add IR_DATA_DIR and LOG_VIEWER_DIR into .env.
junhaoliao Jul 16, 2024
d3fe4a4
Add EOF.
junhaoliao Jul 16, 2024
27b4d0d
Revert wrongly refactored docstring.
junhaoliao Jul 16, 2024
ea337cc
Rename `examples` to `example` in route URLs for consistency.
junhaoliao Jul 16, 2024
ea3210a
Update LOG_VIEWER_DIR default value in .env.
junhaoliao Jul 16, 2024
a9e9cc7
Merge branch 'refs/heads/main' into log_viewer_server
junhaoliao Jul 16, 2024
cf60f36
Specify `IR_DATA_DIR` when launching log-viewer-webui server in start…
junhaoliao Jul 16, 2024
f99a39e
Update package-lock.json.
junhaoliao Jul 16, 2024
a6a543f
Fix failed test cases.
junhaoliao Jul 16, 2024
be5a95f
Refactor server configuration to use settings.json.
junhaoliao Jul 16, 2024
469bf3a
Strip out log-viewer-webui/client deps in clp-package; add settings.j…
junhaoliao Jul 16, 2024
ce6d76a
Clean up component `log-viewer-webui` in CLP package.
junhaoliao Jul 16, 2024
0112dc1
Remove unused environment variables in main.js.
junhaoliao Jul 16, 2024
cf55e8c
Rearrange server initialization code in app.js to ensure fastifyStati…
junhaoliao Jul 16, 2024
8baf2da
lint code.
junhaoliao Jul 16, 2024
fba76c3
Rename task "log-viewer-webui-clients" -> "log-viewer-webui-client".
junhaoliao Jul 19, 2024
1af7e05
Add log-viewer-webui-client checksum to task `package`'s sources.
junhaoliao Jul 19, 2024
8bb6af7
package: Refactor read_and_update_settings_json().
junhaoliao Jul 19, 2024
4cb16ad
package: Add missing PORT envvar setting into start_log_viewer_webui …
junhaoliao Jul 19, 2024
e46f536
log-viewer-webui-server: replace dev dependency ``@babel/plugin-synta…
junhaoliao Jul 19, 2024
c6f3a87
Rename `irDataDir` -> `irFilesDir`.
junhaoliao Jul 19, 2024
094f330
Remove extra line.
junhaoliao Jul 19, 2024
ac01b8d
Make DbManager methods `initMySql()` and `initMongo()` private.
junhaoliao Jul 19, 2024
ae9d86c
Store mysql connection pool instead of connection.
junhaoliao Jul 19, 2024
c125729
Make DbManager member irFilesCollection private.
junhaoliao Jul 19, 2024
36a4f51
Rename `insertExtractIrJob` -> `submitAndWaitForExtractIrJob`.
junhaoliao Jul 19, 2024
9b19d8b
Rename `getExtractedIrMetadata` -> `getExtractedIrFileMetadata`.
junhaoliao Jul 19, 2024
0501a61
Rearrange parseEnvVars return object property order.
junhaoliao Jul 19, 2024
299257f
Move NODE_ENV=test setting from app.test.js to package.json.
junhaoliao Jul 19, 2024
c02c9ee
Remove redundant line.
junhaoliao Jul 19, 2024
f0f05e2
Remove unnecessary export of parseEnvVars.
junhaoliao Jul 19, 2024
06d4f84
Remove unnecessary `await`s on route registrations.
junhaoliao Jul 19, 2024
89a7036
Use shorthand resp.send (return directly) in Fastify route handler.
junhaoliao Jul 19, 2024
56791b5
Add "TODO: add tests for `query` routes." in app.test.js.
junhaoliao Jul 19, 2024
bcb3554
Refactor new read_and_update_settings_json method.
kirkrodrigues Jul 19, 2024
4327c27
Refactor some comments and strings.
kirkrodrigues Jul 19, 2024
1e1a85a
Clean-up previous PR.
kirkrodrigues Jul 19, 2024
85c2954
Nit: Reorder user before pass.
kirkrodrigues Jul 19, 2024
08cce9b
Mark method awaitJobCompletion as private.
junhaoliao Jul 19, 2024
9339a3d
Remove redundant `await` in mysql pool assignment.
junhaoliao Jul 19, 2024
bd96c03
Add webui-log-viewer-server sources to task `package`'s `sources`.
junhaoliao Jul 19, 2024
6a16fd8
Move var G_LOG_VIEWER_WEBUI_SRC_DIR definition lint-tasks.yml -> Task…
junhaoliao Jul 19, 2024
10debf9
Update awaitJobCompletion docstring.
junhaoliao Jul 19, 2024
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
35 changes: 20 additions & 15 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ vars:
G_BUILD_DIR: "{{.ROOT_DIR}}/build"
G_CORE_COMPONENT_BUILD_DIR: "{{.G_BUILD_DIR}}/core"
G_LOG_VIEWER_WEBUI_BUILD_DIR: "{{.G_BUILD_DIR}}/log-viewer-webui"
G_LOG_VIEWER_WEBUI_SRC_DIR: "{{.ROOT_DIR}}/components/log-viewer-webui"
G_METEOR_BUILD_DIR: "{{.G_BUILD_DIR}}/meteor"
G_NODEJS_14_BUILD_DIR: "{{.G_BUILD_DIR}}/nodejs-14"
G_NODEJS_14_BIN_DIR: "{{.G_NODEJS_14_BUILD_DIR}}/bin"
Expand Down Expand Up @@ -73,6 +74,7 @@ tasks:
CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK}}.md5"
OUTPUT_DIR: "{{.G_PACKAGE_BUILD_DIR}}"
sources:
- "{{.G_BUILD_DIR}}/log-viewer-webui-client.md5"
- "{{.G_BUILD_DIR}}/package-venv.md5"
- "{{.G_BUILD_DIR}}/webui.md5"
- "{{.G_BUILD_DIR}}/webui-nodejs.md5"
Expand All @@ -81,6 +83,10 @@ tasks:
- "{{.G_CORE_COMPONENT_BUILD_DIR}}/clp"
- "{{.G_CORE_COMPONENT_BUILD_DIR}}/clp-s"
- "{{.G_CORE_COMPONENT_BUILD_DIR}}/reducer-server"
- "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/server/package.json"
- "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/server/package-lock.json"
- "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/server/settings.json"
- "{{.G_LOG_VIEWER_WEBUI_SRC_DIR}}/server/src/**/*.js"
- "{{.TASKFILE}}"
- "/etc/os-release"
- "components/clp-package-utils/dist/*.whl"
Expand All @@ -94,7 +100,7 @@ tasks:
- "clp-py-utils"
- "init"
- "job-orchestration"
- "log-viewer-webui"
- "log-viewer-webui-client"
- "nodejs-14"
- "package-venv"
- task: "utils:validate-checksum"
Expand Down Expand Up @@ -143,10 +149,15 @@ tasks:
PATH="{{.G_NODEJS_14_BIN_DIR}}":$PATH npm install
- >-
rsync -a
"{{.G_LOG_VIEWER_WEBUI_BUILD_DIR}}/"
"{{.OUTPUT_DIR}}/var/www/log_viewer/"
"{{.G_LOG_VIEWER_WEBUI_BUILD_DIR}}/client"
"{{.OUTPUT_DIR}}/var/www/log_viewer_webui/"
- |-
cd "{{.OUTPUT_DIR}}/var/www/log_viewer/server"
cd components/log-viewer-webui/server/
rsync -a \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wonder, will the code still work if we first run npm clean-install in another directory and copy what's built into var/www/log_viewer_webui?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. However sometimes within node_modules there're symbolic links created during the node dependencies installation, so it's less ideal to copy an initialized node_modules.

package.json package-lock.json settings.json src \
"{{.OUTPUT_DIR}}/var/www/log_viewer_webui/server/"
- |-
cd "{{.OUTPUT_DIR}}/var/www/log_viewer_webui/server"
PATH="{{.G_NODEJS_22_BIN_DIR}}":$PATH npm clean-install
# This command must be last
- task: "utils:compute-checksum"
Expand Down Expand Up @@ -195,19 +206,17 @@ tasks:
vars:
COMPONENT: "{{.TASK}}"

log-viewer-webui:
log-viewer-webui-client:
vars:
CHECKSUM_FILE: "{{.G_BUILD_DIR}}/{{.TASK}}.md5"
OUTPUT_DIR: "{{.G_LOG_VIEWER_WEBUI_BUILD_DIR}}"
sources:
- "{{.G_BUILD_DIR}}/log-viewer-modules.md5"
- "{{.TASKFILE}}"
- "client/package.json"
- "client/src/**/*.css"
- "client/src/**/*.jsx"
- "client/src/package.json"
- "client/src/webpack.config.js"
- "server/src/**/*.js"
- "server/src/**/package.json"
dir: "components/log-viewer-webui"
generates: ["{{.CHECKSUM_FILE}}"]
deps:
Expand All @@ -219,14 +228,10 @@ tasks:
DATA_DIR: "{{.OUTPUT_DIR}}"
cmds:
- "rm -rf '{{.OUTPUT_DIR}}'"
- "rsync -a client {{.OUTPUT_DIR}}/"
- |-
cd "{{.OUTPUT_DIR}}/client"
PATH="{{.G_NODEJS_22_BIN_DIR}}":$PATH npm run build
- "mkdir {{.OUTPUT_DIR}}/server"
- |-
cd server
rsync -a src package-lock.json package.json {{.OUTPUT_DIR}}/server/
cd client
PATH="{{.G_NODEJS_22_BIN_DIR}}":$PATH npm run build -- \
--output-path "{{.OUTPUT_DIR}}/client"
- task: "utils:compute-checksum"
vars:
DATA_DIR: "{{.OUTPUT_DIR}}"
Expand Down
10 changes: 5 additions & 5 deletions components/clp-package-utils/clp_package_utils/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,11 +497,11 @@ def validate_webui_config(
validate_port(f"{WEBUI_COMPONENT_NAME}.port", clp_config.webui.host, clp_config.webui.port)


def validate_log_viewer_config(clp_config: CLPConfig, logs_dir: pathlib.Path):
try:
validate_path_could_be_dir(logs_dir)
except ValueError as ex:
raise ValueError(f"{LOG_VIEWER_WEBUI_COMPONENT_NAME} logs directory is invalid: {ex}")
def validate_log_viewer_webui_config(clp_config: CLPConfig, settings_json_path: pathlib.Path):
if not settings_json_path.exists():
raise ValueError(
f"{WEBUI_COMPONENT_NAME} {settings_json_path} is not a valid path to settings.json"
)

validate_port(
f"{LOG_VIEWER_WEBUI_COMPONENT_NAME}.port",
Expand Down
79 changes: 55 additions & 24 deletions components/clp-package-utils/clp_package_utils/scripts/start_clp.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
validate_and_load_queue_credentials_file,
validate_and_load_redis_credentials_file,
validate_db_config,
validate_log_viewer_config,
validate_log_viewer_webui_config,
validate_queue_config,
validate_redis_config,
validate_reducer_config,
Expand Down Expand Up @@ -668,13 +668,13 @@ def generic_start_worker(
logger.info(f"Started {component_name}.")


def update_meteor_settings(
def update_settings_object(
parent_key_prefix: str,
settings: Dict[str, Any],
updates: Dict[str, Any],
):
"""
Recursively updates the given Meteor settings object with the values from `updates`.
Recursively updates the given settings object with the values from `updates`.
:param parent_key_prefix: The prefix for keys at this level in the settings dictionary.
:param settings: The settings to update.
Expand All @@ -686,11 +686,25 @@ def update_meteor_settings(
error_msg = f"{parent_key_prefix}{key} is not a valid configuration key for the webui."
raise ValueError(error_msg)
if isinstance(value, dict):
update_meteor_settings(f"{parent_key_prefix}{key}.", settings[key], value)
update_settings_object(f"{parent_key_prefix}{key}.", settings[key], value)
else:
settings[key] = updates[key]


def read_and_update_settings_json(settings_file_path: pathlib.Path, updates: Dict[str, Any]):
"""
Reads and updates a settings JSON file.
:param settings_file_path:
:param updates:
"""
with open(settings_file_path, "r") as settings_json_file:
settings_object = json.loads(settings_json_file.read())
update_settings_object("", settings_object, updates)

return settings_object


def start_webui(instance_id: str, clp_config: CLPConfig, mounts: CLPDockerMounts):
component_name = WEBUI_COMPONENT_NAME
logger.info(f"Starting {component_name}...")
Expand All @@ -710,8 +724,8 @@ def start_webui(instance_id: str, clp_config: CLPConfig, mounts: CLPDockerMounts
webui_logs_dir.mkdir(exist_ok=True, parents=True)

container_webui_logs_dir = pathlib.Path("/") / "var" / "log" / component_name
with open(settings_json_path, "r") as settings_json_file:
meteor_settings = json.loads(settings_json_file.read())

# Read and update settings.json
meteor_settings_updates = {
"private": {
"SqlDbHost": clp_config.database.host,
Expand All @@ -726,7 +740,7 @@ def start_webui(instance_id: str, clp_config: CLPConfig, mounts: CLPDockerMounts
"ClpStorageEngine": clp_config.package.storage_engine,
},
}
update_meteor_settings("", meteor_settings, meteor_settings_updates)
meteor_settings = read_and_update_settings_json(settings_json_path, meteor_settings_updates)

# Start container
# fmt: off
Expand Down Expand Up @@ -769,24 +783,43 @@ def start_webui(instance_id: str, clp_config: CLPConfig, mounts: CLPDockerMounts
logger.info(f"Started {component_name}.")


def start_log_viewer_webui(instance_id: str, clp_config: CLPConfig, mounts: CLPDockerMounts):
def start_log_viewer_webui(
instance_id: str,
clp_config: CLPConfig,
container_clp_config: CLPConfig,
mounts: CLPDockerMounts,
):
component_name = LOG_VIEWER_WEBUI_COMPONENT_NAME
logger.info(f"Starting {component_name}...")

container_name = f"clp-{component_name}-{instance_id}"
if container_exists(container_name):
return

log_viewer_webui_logs_dir = clp_config.logs_directory / component_name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add log_viewer_webui_logs_dir back once logging to file is enabled in log-viewer-webui-server.

container_log_viewer_dir = CONTAINER_CLP_HOME / "var" / "www" / "log_viewer"
node_path = str(container_log_viewer_dir / "server" / "node_modules")

validate_log_viewer_config(clp_config, log_viewer_webui_logs_dir)

# Create directories
log_viewer_webui_logs_dir.mkdir(exist_ok=True, parents=True)
container_log_viewer_webui_dir = CONTAINER_CLP_HOME / "var" / "www" / "log_viewer_webui"
node_path = str(container_log_viewer_webui_dir / "server" / "node_modules")
settings_json_path = (
get_clp_home() / "var" / "www" / "log_viewer_webui" / "server" / "settings.json"
)

container_log_viewer_webui_logs_dir = pathlib.Path("/") / "var" / "log" / component_name
validate_log_viewer_webui_config(clp_config, settings_json_path)

# Read, update, and write back settings.json
settings_json_updates = {
"SqlDbHost": clp_config.database.host,
kirkrodrigues marked this conversation as resolved.
Show resolved Hide resolved
"SqlDbPort": clp_config.database.port,
"SqlDbName": clp_config.database.name,
"SqlDbQueryJobsTableName": QUERY_JOBS_TABLE_NAME,
"MongoDbHost": clp_config.results_cache.host,
"MongoDbPort": clp_config.results_cache.port,
"MongoDbName": clp_config.results_cache.db_name,
"MongoDbIrFilesCollectionName": clp_config.results_cache.ir_collection_name,
"ClientDir": str(container_log_viewer_webui_dir / "client"),
"IrFilesDir": str(container_clp_config.ir_output.directory),
}
settings_json = read_and_update_settings_json(settings_json_path, settings_json_updates)
with open(settings_json_path, "w") as settings_json_file:
settings_json_file.write(json.dumps(settings_json))

# Start container
# fmt: off
Expand All @@ -797,19 +830,17 @@ def start_log_viewer_webui(instance_id: str, clp_config: CLPConfig, mounts: CLPD
"--name", container_name,
"--log-driver", "local",
"-e", f"NODE_PATH={node_path}",
"-e", f"CLIENT_DIR={container_log_viewer_dir}/client/dist",
"-e", f"PORT={clp_config.log_viewer_webui.port}",
kirkrodrigues marked this conversation as resolved.
Show resolved Hide resolved
"-e", f"HOST={clp_config.log_viewer_webui.host}",
"-e", f"PORT={clp_config.log_viewer_webui.port}",
"-e", f"CLP_DB_USER={clp_config.database.username}",
"-e", f"CLP_DB_PASS={clp_config.database.password}",
"-e", f"NODE_ENV=production",
"-u", f"{os.getuid()}:{os.getgid()}",
]
# fmt: on
necessary_mounts = [
mounts.clp_home,
mounts.ir_output_dir,
DockerMount(
DockerMountType.BIND, log_viewer_webui_logs_dir, container_log_viewer_webui_logs_dir
),
]
for mount in necessary_mounts:
if mount:
Expand All @@ -819,7 +850,7 @@ def start_log_viewer_webui(instance_id: str, clp_config: CLPConfig, mounts: CLPD

node_cmd = [
str(CONTAINER_CLP_HOME / "bin" / "node-22"),
str(container_log_viewer_dir / "server" / "src" / "main.js"),
str(container_log_viewer_webui_dir / "server" / "src" / "main.js"),
]
cmd = container_cmd + node_cmd
subprocess.run(cmd, stdout=subprocess.DEVNULL, check=True)
Expand Down Expand Up @@ -1046,7 +1077,7 @@ def main(argv):
if target in (ALL_TARGET_NAME, WEBUI_COMPONENT_NAME):
start_webui(instance_id, clp_config, mounts)
if target in (ALL_TARGET_NAME, LOG_VIEWER_WEBUI_COMPONENT_NAME):
start_log_viewer_webui(instance_id, clp_config, mounts)
start_log_viewer_webui(instance_id, clp_config, container_clp_config, mounts)

except Exception as ex:
if type(ex) == ValueError:
Expand Down
1 change: 0 additions & 1 deletion components/clp-py-utils/clp_py_utils/clp_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,6 @@ def validate_logging_level(cls, field):
class LogViewerWebUi(BaseModel):
host: str = "localhost"
port: int = 3000
logging_level: str = "INFO"

@validator("host")
def validate_host(cls, field):
Expand Down
5 changes: 5 additions & 0 deletions components/log-viewer-webui/server/.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
CLIENT_DIR=../client/dist
IR_DATA_DIR=../../../build/clp-package/var/data/ir
LOG_VIEWER_DIR=../yscope-log-viewer/dist
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Henry8192 Kindly update here once your yscope-log-viewer integration PR is ready.


HOST=localhost
PORT=3000
CLP_DB_USER=clp-user
CLP_DB_PASS=
3 changes: 3 additions & 0 deletions components/log-viewer-webui/server/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Local development
.env.local

# Testing
/.tap
Loading