code: def test_log_get_subdir(ray_start_with_dashboard):
      assert (
          wait_until_server_available(
              ray_start_with_dashboard.address_info["webui_url"]
          )
          is True
      )
      webui_url = ray_start_with_dashboard.address_info["webui_url"]
      webui_url = format_web_url(webui_url)
      node_id = list_nodes()[0]["node_id"]
  
      log_dir = (
          ray._private.worker.global_worker.node.get_logs_dir_path()
      )
      subdir = "test_subdir"
      file = "test_#file.log"
      path = Path(log_dir) / subdir / file
      path.parent.mkdir(parents=True, exist_ok=True)
      path.write_text("test log")
  
      # HTTP endpoint
      def verify():
          # Direct logs stream
          response = requests.get(
              webui_url
              + f"/api/v0/logs/file?node_id={node_id}"
              + f"&filename={urllib.parse.quote('test_subdir/test_#file.log')}"
          )
          assert response.status_code == 200, response.reason
          assert "test log" in response.text
          return True
  
      wait_for_condition(verify)
  
      # get log SDK
      def verify():
          logs = "".join(
              get_log(
                  node_id=node_id, filename="test_subdir/test_#file.log"
              )
          )
          assert "test log" in logs
          return True
  
      wait_for_condition(verify)
  
imports: import json
  import os
  import sys
  import asyncio
  from typing import List
  import urllib
  from unittest.mock import MagicMock, AsyncMock
  import pytest
  from ray.util.state.state_cli import logs_state_cli_group
  from ray.util.state import list_jobs
  import requests
  from click.testing import CliRunner
  import grpc
  from pathlib import Path
  import ray
  from ray._private.test_utils import format_web_url, wait_for_condition, wait_until_server_available
  from ray._private.ray_constants import LOG_PREFIX_TASK_ATTEMPT_START, LOG_PREFIX_TASK_ATTEMPT_END
  from ray._raylet import ActorID, NodeID, TaskID, WorkerID
  from ray.core.generated.common_pb2 import Address
  from ray.core.generated.gcs_service_pb2 import GetTaskEventsReply
  from ray.core.generated.reporter_pb2 import ListLogsReply, StreamLogReply
  from ray.core.generated.gcs_pb2 import ActorTableData, TaskEvents, TaskStateUpdate, TaskLogInfo
  from ray.dashboard.modules.actor.actor_head import actor_table_data_to_dict
  from ray.dashboard.modules.log.log_agent import find_offset_of_content_in_file, find_end_offset_file, find_end_offset_next_n_lines_from_offset, find_start_offset_last_n_lines_from_offset, LogAgentV1Grpc
  from ray.dashboard.modules.log.log_agent import _stream_log_in_chunk
  from ray.dashboard.modules.log.log_manager import LogsManager
  from ray.dashboard.tests.conftest import *
  from ray.util.state import get_log, list_logs, list_nodes, list_workers
  from ray.util.state.common import GetLogOptions
  from ray.util.state.exception import DataSourceUnavailable, RayStateApiException
  from ray.util.state.state_manager import StateDataSourceClient
label_desc: Use image node_id 17 for calling a global function with example usage: test_log_get_subdir(ray_start_with_dashboard) and returns: True, True