Преглед изворни кода

select logs by app id in v2 (#3760)

Feroze Mohideen пре 2 година
родитељ
комит
7f337b695e

+ 15 - 5
api/server/handlers/porter_app/logs_apply_v2.go

@@ -14,6 +14,7 @@ import (
 	"github.com/porter-dev/porter/api/server/shared"
 	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/server/shared/requestutils"
 	"github.com/porter-dev/porter/api/types"
 	porter_agent "github.com/porter-dev/porter/internal/kubernetes/porter_agent/v2"
 	"github.com/porter-dev/porter/internal/models"
@@ -42,7 +43,7 @@ func NewAppLogsHandler(
 type AppLogsRequest struct {
 	DeploymentTargetID string    `schema:"deployment_target_id"`
 	ServiceName        string    `schema:"service_name"`
-	AppName            string    `schema:"app_name"`
+	AppID              uint      `schema:"app_id"`
 	Limit              uint      `schema:"limit"`
 	StartRange         time.Time `schema:"start_range,omitempty"`
 	EndRange           time.Time `schema:"end_range,omitempty"`
@@ -53,6 +54,7 @@ type AppLogsRequest struct {
 
 const (
 	lokiLabel_PorterAppName       = "porter_run_app_name"
+	lokiLabel_PorterAppID         = "porter_run_app_id"
 	lokiLabel_PorterServiceName   = "porter_run_service_name"
 	lokiLabel_PorterAppRevisionID = "porter_run_app_revision_id"
 	lokiLabel_DeploymentTargetId  = "porter_run_deployment_target_id"
@@ -74,12 +76,19 @@ func (c *AppLogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	if request.AppName == "" {
-		err := telemetry.Error(ctx, span, nil, "must provide app name")
+	appName, reqErr := requestutils.GetURLParamString(r, types.URLParamPorterAppName)
+	if reqErr != nil {
+		err := telemetry.Error(ctx, span, reqErr, "porter app name not found in request")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
+		return
+	}
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "app-name", Value: appName})
+
+	if request.AppID == 0 {
+		err := telemetry.Error(ctx, span, nil, "must provide app id")
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
 		return
 	}
-	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "app-name", Value: request.AppName})
 
 	if request.ServiceName == "" {
 		err := telemetry.Error(ctx, span, nil, "must provide service name")
@@ -148,7 +157,8 @@ func (c *AppLogsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 	matchLabels := map[string]string{
 		lokiLabel_Namespace:     namespace,
-		lokiLabel_PorterAppName: request.AppName,
+		lokiLabel_PorterAppName: appName,
+		lokiLabel_PorterAppID:   fmt.Sprintf("%d", request.AppID),
 	}
 
 	if request.ServiceName != "all" {

+ 7 - 4
api/server/handlers/porter_app/stream_logs.go

@@ -16,6 +16,7 @@ import (
 	"github.com/porter-dev/porter/api/server/shared"
 	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/server/shared/requestutils"
 	"github.com/porter-dev/porter/api/server/shared/websocket"
 	"github.com/porter-dev/porter/api/types"
 	"github.com/porter-dev/porter/internal/models"
@@ -54,12 +55,13 @@ func (c *StreamLogsLokiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 		return
 	}
 
-	if request.AppName == "" {
-		err := telemetry.Error(ctx, span, nil, "must provide app name")
+	appName, reqErr := requestutils.GetURLParamString(r, types.URLParamPorterAppName)
+	if reqErr != nil {
+		err := telemetry.Error(ctx, span, reqErr, "porter app name not found in request")
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
 		return
 	}
-	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "app-name", Value: request.AppName})
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "app-name", Value: appName})
 
 	if request.ServiceName == "" {
 		err := telemetry.Error(ctx, span, nil, "must provide service name")
@@ -126,8 +128,9 @@ func (c *StreamLogsLokiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 
 	labels := []string{
 		fmt.Sprintf("%s=%s", lokiLabel_Namespace, namespace),
-		fmt.Sprintf("%s=%s", lokiLabel_PorterAppName, request.AppName),
+		fmt.Sprintf("%s=%s", lokiLabel_PorterAppName, appName),
 		fmt.Sprintf("%s=%s", lokiLabel_DeploymentTargetId, request.DeploymentTargetID),
+		fmt.Sprintf("%s=%s", lokiLabel_PorterAppID, fmt.Sprintf("%d", request.AppID)),
 	}
 
 	if request.ServiceName != "all" {

+ 2 - 2
api/server/router/porter_app.go

@@ -891,7 +891,7 @@ func getPorterAppRoutes(
 		Router:   r,
 	})
 
-	// GET /api/projects/{project_id}/clusters/{cluster_id}/apps/logs -> cluster.NewAppLogsHandler
+	// GET /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/logs -> cluster.NewAppLogsHandler
 	appLogsEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbGet,
@@ -920,7 +920,7 @@ func getPorterAppRoutes(
 		Router:   r,
 	})
 
-	// GET /api/projects/{project_id}/clusters/{cluster_id}/apps/logs/loki -> namespace.NewStreamLogsLokiHandler
+	// GET /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/logs/loki -> namespace.NewStreamLogsLokiHandler
 	streamLogsLokiEndpoint := factory.NewAPIEndpoint(
 		&types.APIRequestMetadata{
 			Verb:   types.APIVerbGet,

+ 1 - 0
dashboard/src/lib/hooks/useJobs.ts

@@ -10,6 +10,7 @@ const jobRunValidator = z.object({
         labels: z.object({
             "porter.run/app-revision-id": z.string(),
             "porter.run/service-name": z.string(),
+            "porter.run/app-id": z.string(),
         }),
         creationTimestamp: z.string(),
         uid: z.string(),

+ 1 - 0
dashboard/src/main/home/app-dashboard/app-view/AppView.tsx

@@ -12,6 +12,7 @@ import AppHeader from "./AppHeader";
 import { LatestRevisionProvider } from "./LatestRevisionContext";
 
 export const porterAppValidator = z.object({
+  id: z.number(),
   name: z.string(),
   git_branch: z.string().optional(),
   git_repo_id: z.number().optional(),

+ 2 - 1
dashboard/src/main/home/app-dashboard/app-view/tabs/LogsTab.tsx

@@ -3,7 +3,7 @@ import Logs from "../../validate-apply/logs/Logs"
 import { useLatestRevision } from "../LatestRevisionContext";
 
 const LogsTab: React.FC = () => {
-    const { projectId, clusterId, latestProto, deploymentTarget } = useLatestRevision();
+    const { projectId, clusterId, latestProto, deploymentTarget, porterApp } = useLatestRevision();
 
     const appName = latestProto.name
     const serviceNames = Object.keys(latestProto.services)
@@ -16,6 +16,7 @@ const LogsTab: React.FC = () => {
             serviceNames={serviceNames}
             deploymentTargetId={deploymentTarget.id}
             filterPredeploy={true}
+            appId={porterApp.id}
         />
     );
 };

+ 2 - 2
dashboard/src/main/home/app-dashboard/app-view/tabs/activity-feed/events/cards/AppEventCard.tsx

@@ -36,7 +36,7 @@ const AppEventCard: React.FC<Props> = ({ event, deploymentTargetId, projectId, c
         {
           start_range: dayjs(event.created_at).subtract(1, 'minute').toISOString(),
           end_range: dayjs(event.updated_at).add(1, 'minute').toISOString(),
-          app_name: event.metadata.app_name,
+          app_id: event.porter_app_id,
           service_name: event.metadata.service_name,
           deployment_target_id: deploymentTargetId,
           limit: 1000,
@@ -45,7 +45,7 @@ const AppEventCard: React.FC<Props> = ({ event, deploymentTargetId, projectId, c
         {
           project_id: projectId,
           cluster_id: clusterId,
-          app_name: appName,
+          porter_app_name: appName,
         }
       )
 

+ 2 - 1
dashboard/src/main/home/app-dashboard/app-view/tabs/activity-feed/events/focus-views/PredeployEventFocusView.tsx

@@ -19,7 +19,7 @@ type Props = {
 const PreDeployEventFocusView: React.FC<Props> = ({
   event,
 }) => {
-  const { projectId, clusterId, latestProto, deploymentTarget } = useLatestRevision();
+  const { projectId, clusterId, latestProto, deploymentTarget, porterApp } = useLatestRevision();
 
   const appName = latestProto.name
   const serviceNames = [`${latestProto.name}-predeploy`]
@@ -66,6 +66,7 @@ const PreDeployEventFocusView: React.FC<Props> = ({
         deploymentTargetId={deploymentTarget.id}
         appRevisionId={event.metadata.app_revision_id}
         logFilterNames={["service_name"]}
+        appId={porterApp.id}
       />
     </>
   );

+ 1 - 0
dashboard/src/main/home/app-dashboard/validate-apply/jobs/JobRunDetails.tsx

@@ -74,6 +74,7 @@ const JobRunDetails: React.FC<Props> = ({
                     startTime: dayjs(jobRun.status.startTime ?? jobRun.metadata.creationTimestamp).subtract(30, 'second'),
                     endTime: jobRun.status.completionTime != null ? dayjs(jobRun.status.completionTime).add(30, 'second') : undefined,
                 }}
+                appId={parseInt(jobRun.metadata.labels["porter.run/app-id"])}
             />
         </>
     );

+ 3 - 0
dashboard/src/main/home/app-dashboard/validate-apply/logs/Logs.tsx

@@ -42,6 +42,7 @@ type Props = {
         endTime?: Dayjs;
     };
     filterPredeploy?: boolean;
+    appId: number;
 };
 
 const Logs: React.FC<Props> = ({
@@ -54,6 +55,7 @@ const Logs: React.FC<Props> = ({
     timeRange,
     logFilterNames = ["service_name", "revision", "output_stream"],
     filterPredeploy = false,
+    appId,
 }) => {
     const { search } = useLocation();
     const queryParams = new URLSearchParams(search);
@@ -194,6 +196,7 @@ const Logs: React.FC<Props> = ({
         appRevisionId,
         filterPredeploy,
         timeRange,
+        appID: appId,
     });
 
     useEffect(() => {

+ 4 - 2
dashboard/src/main/home/app-dashboard/validate-apply/logs/utils.ts

@@ -56,6 +56,7 @@ export const useLogs = ({
   appRevisionId = "",
   timeRange,
   filterPredeploy,
+  appID,
 }: {
   projectID: number,
   clusterID: number,
@@ -75,6 +76,7 @@ export const useLogs = ({
     endTime?: Dayjs,
   },
   filterPredeploy: boolean,
+  appID: number,
 }
 ) => {
   const [isLive, setIsLive] = useState<boolean>(!setDate && (timeRange?.startTime == null && timeRange?.endTime == null));
@@ -180,11 +182,11 @@ export const useLogs = ({
     const websocketBaseURL = `/api/projects/${projectID}/clusters/${clusterID}/apps/${appName}/logs/loki`;
 
     const searchParams = {
-      app_name: appName,
       service_name: serviceName,
       deployment_target_id: deploymentTargetId,
       search_param: searchParam,
       app_revision_id: appRevisionId,
+      app_id: appID.toString(),
     }
 
     const q = new URLSearchParams(searchParams).toString();
@@ -272,7 +274,7 @@ export const useLogs = ({
   }> => {
     try {
       const getLogsReq = {
-        app_name: appName,
+        app_id: appID,
         service_name: serviceName,
         deployment_target_id: deploymentTargetId,
         search_param: searchParam,

+ 37 - 50
dashboard/src/shared/api.tsx

@@ -280,7 +280,7 @@ const getLogsWithinTimeRange = baseApi<
 
 const appLogs = baseApi<
   {
-    app_name: string;
+    app_id: number;
     service_name: string;
     deployment_target_id: string;
     limit: number;
@@ -352,9 +352,8 @@ const getFeedEvents = baseApi<
   }
 >("GET", (pathParams) => {
   let { project_id, cluster_id, stack_name, page } = pathParams;
-  return `/api/projects/${project_id}/clusters/${cluster_id}/applications/${stack_name}/events?page=${
-    page || 1
-  }`;
+  return `/api/projects/${project_id}/clusters/${cluster_id}/applications/${stack_name}/events?page=${page || 1
+    }`;
 });
 
 const createEnvironment = baseApi<
@@ -779,11 +778,9 @@ const detectBuildpack = baseApi<
     branch: string;
   }
 >("GET", (pathParams) => {
-  return `/api/projects/${pathParams.project_id}/gitrepos/${
-    pathParams.git_repo_id
-  }/repos/${pathParams.kind}/${pathParams.owner}/${
-    pathParams.name
-  }/${encodeURIComponent(pathParams.branch)}/buildpack/detect`;
+  return `/api/projects/${pathParams.project_id}/gitrepos/${pathParams.git_repo_id
+    }/repos/${pathParams.kind}/${pathParams.owner}/${pathParams.name
+    }/${encodeURIComponent(pathParams.branch)}/buildpack/detect`;
 });
 
 const detectGitlabBuildpack = baseApi<
@@ -814,11 +811,9 @@ const getBranchContents = baseApi<
     branch: string;
   }
 >("GET", (pathParams) => {
-  return `/api/projects/${pathParams.project_id}/gitrepos/${
-    pathParams.git_repo_id
-  }/repos/${pathParams.kind}/${pathParams.owner}/${
-    pathParams.name
-  }/${encodeURIComponent(pathParams.branch)}/contents`;
+  return `/api/projects/${pathParams.project_id}/gitrepos/${pathParams.git_repo_id
+    }/repos/${pathParams.kind}/${pathParams.owner}/${pathParams.name
+    }/${encodeURIComponent(pathParams.branch)}/contents`;
 });
 
 const getProcfileContents = baseApi<
@@ -834,11 +829,9 @@ const getProcfileContents = baseApi<
     branch: string;
   }
 >("GET", (pathParams) => {
-  return `/api/projects/${pathParams.project_id}/gitrepos/${
-    pathParams.git_repo_id
-  }/repos/${pathParams.kind}/${pathParams.owner}/${
-    pathParams.name
-  }/${encodeURIComponent(pathParams.branch)}/procfile`;
+  return `/api/projects/${pathParams.project_id}/gitrepos/${pathParams.git_repo_id
+    }/repos/${pathParams.kind}/${pathParams.owner}/${pathParams.name
+    }/${encodeURIComponent(pathParams.branch)}/procfile`;
 });
 
 const getPorterYamlContents = baseApi<
@@ -854,11 +847,9 @@ const getPorterYamlContents = baseApi<
     branch: string;
   }
 >("GET", (pathParams) => {
-  return `/api/projects/${pathParams.project_id}/gitrepos/${
-    pathParams.git_repo_id
-  }/repos/${pathParams.kind}/${pathParams.owner}/${
-    pathParams.name
-  }/${encodeURIComponent(pathParams.branch)}/porteryaml`;
+  return `/api/projects/${pathParams.project_id}/gitrepos/${pathParams.git_repo_id
+    }/repos/${pathParams.kind}/${pathParams.owner}/${pathParams.name
+    }/${encodeURIComponent(pathParams.branch)}/porteryaml`;
 });
 
 const parsePorterYaml = baseApi<
@@ -895,11 +886,9 @@ const getBranchHead = baseApi<
     branch: string;
   }
 >("GET", (pathParams) => {
-  return `/api/projects/${pathParams.project_id}/gitrepos/${
-    pathParams.git_repo_id
-  }/repos/${pathParams.kind}/${pathParams.owner}/${
-    pathParams.name
-  }/${encodeURIComponent(pathParams.branch)}/head`;
+  return `/api/projects/${pathParams.project_id}/gitrepos/${pathParams.git_repo_id
+    }/repos/${pathParams.kind}/${pathParams.owner}/${pathParams.name
+    }/${encodeURIComponent(pathParams.branch)}/head`;
 });
 
 const validatePorterApp = baseApi<
@@ -925,21 +914,21 @@ const validatePorterApp = baseApi<
 
 const createApp = baseApi<
   | {
-      name: string;
-      type: "github";
-      git_repo_id: number;
-      git_branch: string;
-      git_repo_name: string;
-      porter_yaml_path: string;
-    }
+    name: string;
+    type: "github";
+    git_repo_id: number;
+    git_branch: string;
+    git_repo_name: string;
+    porter_yaml_path: string;
+  }
   | {
-      name: string;
-      type: "docker-registry";
-      image: {
-        repository: string;
-        tag: string;
-      };
-    },
+    name: string;
+    type: "docker-registry";
+    image: {
+      repository: string;
+      tag: string;
+    };
+  },
   {
     project_id: number;
     cluster_id: number;
@@ -1070,7 +1059,7 @@ const getAppTemplate = baseApi<
     cluster_id: number;
     porter_app_name: string;
   }>("GET", ({ project_id, cluster_id, porter_app_name }) => {
-  return `/api/projects/${project_id}/clusters/${cluster_id}/apps/${porter_app_name}/templates`;
+    return `/api/projects/${project_id}/clusters/${cluster_id}/apps/${porter_app_name}/templates`;
   })
 
 const getGitlabProcfileContents = baseApi<
@@ -1977,11 +1966,9 @@ const getEnvGroup = baseApi<
     version?: number;
   }
 >("GET", (pathParams) => {
-  return `/api/projects/${pathParams.id}/clusters/${
-    pathParams.cluster_id
-  }/namespaces/${pathParams.namespace}/envgroup?name=${pathParams.name}${
-    pathParams.version ? "&version=" + pathParams.version : ""
-  }`;
+  return `/api/projects/${pathParams.id}/clusters/${pathParams.cluster_id
+    }/namespaces/${pathParams.namespace}/envgroup?name=${pathParams.name}${pathParams.version ? "&version=" + pathParams.version : ""
+    }`;
 });
 
 const getConfigMap = baseApi<
@@ -3039,7 +3026,7 @@ const removeStackEnvGroup = baseApi<
     `/api/v1/projects/${project_id}/clusters/${cluster_id}/namespaces/${namespace}/stacks/${stack_id}/remove_env_group/${env_group_name}`
 );
 
-const getGithubStatus = baseApi<{}, {}>("GET", ({}) => `/api/status/github`);
+const getGithubStatus = baseApi<{}, {}>("GET", ({ }) => `/api/status/github`);
 
 const createSecretAndOpenGitHubPullRequest = baseApi<
   {