diff --git a/pkg/pipeline/ArgoWorkflowExecutor.go b/pkg/pipeline/ArgoWorkflowExecutor.go index fdf5ffdd1b..dc4755e9cb 100644 --- a/pkg/pipeline/ArgoWorkflowExecutor.go +++ b/pkg/pipeline/ArgoWorkflowExecutor.go @@ -110,7 +110,7 @@ func (impl *ArgoWorkflowExecutorImpl) ExecuteWorkflow(workflowTemplate bean.Work func (impl *ArgoWorkflowExecutorImpl) updateBlobStorageConfig(workflowTemplate bean.WorkflowTemplate, cdTemplate *v1alpha1.Template) { cdTemplate.ArchiveLocation = &v1alpha1.ArtifactLocation{ - ArchiveLogs: &workflowTemplate.BlobStorageConfigured, + ArchiveLogs: &workflowTemplate.ArchiveLogs, } if workflowTemplate.BlobStorageConfigured { var s3Artifact *v1alpha1.S3Artifact diff --git a/pkg/pipeline/CdConfig.go b/pkg/pipeline/CdConfig.go index e4c12d2a92..5330a7fb42 100644 --- a/pkg/pipeline/CdConfig.go +++ b/pkg/pipeline/CdConfig.go @@ -75,6 +75,7 @@ type CdConfig struct { UseBlobStorageConfigInCdWorkflow bool `env:"USE_BLOB_STORAGE_CONFIG_IN_CD_WORKFLOW" envDefault:"true"` BaseLogLocationPath string `env:"BASE_LOG_LOCATION_PATH" envDefault:"/home/devtron/"` CdWorkflowExecutorType pipelineConfig.WorkflowExecutorType `env:"CD_WORKFLOW_EXECUTOR_TYPE" envDefault:"AWF"` + InAppLoggingEnabled bool `env:"IN_APP_LOGGING_ENABLED" envDefault:"false"` } func GetCdConfig() (*CdConfig, error) { diff --git a/pkg/pipeline/CdHandler.go b/pkg/pipeline/CdHandler.go index ca3c78ea98..4b85cbc857 100644 --- a/pkg/pipeline/CdHandler.go +++ b/pkg/pipeline/CdHandler.go @@ -634,7 +634,7 @@ func (impl *CdHandlerImpl) UpdateWorkflow(workflowStatus v1alpha1.WorkflowStatus savedWorkflow.Message = message savedWorkflow.FinishedOn = workflowStatus.FinishedAt.Time savedWorkflow.Name = workflowName - savedWorkflow.LogLocation = wfStatusRs.LogLocation + // removed log location from here since we are saving it at trigger savedWorkflow.PodName = podName savedWorkflow.UpdatedOn = time.Now() savedWorkflow.UpdatedBy = 1 @@ -998,6 +998,7 @@ func (impl *CdHandlerImpl) FetchCdWorkflowDetails(appId int, environmentId int, GitTriggers: gitTriggers, BlobStorageEnabled: workflow.BlobStorageEnabled, IsVirtualEnvironment: workflowR.CdWorkflow.Pipeline.Environment.IsVirtualEnvironment, + PodName: workflowR.PodName, } return workflowResponse, nil diff --git a/pkg/pipeline/CdWorkflowService.go b/pkg/pipeline/CdWorkflowService.go index c61fd0019b..56fa27dbad 100644 --- a/pkg/pipeline/CdWorkflowService.go +++ b/pkg/pipeline/CdWorkflowService.go @@ -110,6 +110,9 @@ type CdWorkflowRequest struct { CloudProvider blob_storage.BlobStorageType `json:"cloudProvider"` AzureBlobConfig *blob_storage.AzureBlobConfig `json:"azureBlobConfig"` GcpBlobConfig *blob_storage.GcpBlobConfig `json:"gcpBlobConfig"` + BlobStorageLogsKey string `json:"blobStorageLogsKey"` + InAppLoggingEnabled bool `json:"inAppLoggingEnabled"` + WorkflowPrefixForLog string `json:"workflowPrefixForLog"` DefaultAddressPoolBaseCidr string `json:"defaultAddressPoolBaseCidr"` DefaultAddressPoolSize int `json:"defaultAddressPoolSize"` DeploymentTriggeredBy string `json:"deploymentTriggeredBy,omitempty"` @@ -147,8 +150,13 @@ func (impl *CdWorkflowServiceImpl) SubmitWorkflow(workflowRequest *CdWorkflowReq workflowRequest.IsExtRun = true } ciCdTriggerEvent := CiCdTriggerEvent{ + Type: cdStage, CdRequest: workflowRequest, } + + // key will be used for log archival through in-app logging + ciCdTriggerEvent.CdRequest.BlobStorageLogsKey = fmt.Sprintf("%s/%s", impl.cdConfig.DefaultBuildLogsKeyPrefix, workflowRequest.WorkflowPrefixForLog) + ciCdTriggerEvent.CdRequest.InAppLoggingEnabled = impl.cdConfig.InAppLoggingEnabled || (workflowRequest.WorkflowExecutor == pipelineConfig.WORKFLOW_EXECUTOR_TYPE_SYSTEM) workflowJson, err := json.Marshal(&ciCdTriggerEvent) if err != nil { impl.Logger.Errorw("error occurred while marshalling ciCdTriggerEvent", "error", err) @@ -224,6 +232,7 @@ func (impl *CdWorkflowServiceImpl) SubmitWorkflow(workflowRequest *CdWorkflowReq workflowTemplate.Tolerations = []v12.Toleration{{Key: impl.cdConfig.TaintKey, Value: impl.cdConfig.TaintValue, Operator: v12.TolerationOpEqual, Effect: v12.TaintEffectNoSchedule}} workflowTemplate.Volumes = ExtractVolumesFromCmCs(workflowConfigMaps, workflowSecrets) workflowTemplate.ArchiveLogs = storageConfigured + workflowTemplate.ArchiveLogs = workflowTemplate.ArchiveLogs && !ciCdTriggerEvent.CdRequest.InAppLoggingEnabled workflowTemplate.RestartPolicy = v12.RestartPolicyNever if len(impl.cdConfig.NodeLabel) > 0 { @@ -235,11 +244,13 @@ func (impl *CdWorkflowServiceImpl) SubmitWorkflow(workflowRequest *CdWorkflowReq reqCpu := impl.cdConfig.ReqCpu reqMem := impl.cdConfig.ReqMem + eventEnv := v12.EnvVar{Name: "CI_CD_EVENT", Value: string(workflowJson)} + inAppLoggingEnv := v12.EnvVar{Name: "IN_APP_LOGGING", Value: strconv.FormatBool(ciCdTriggerEvent.CdRequest.InAppLoggingEnabled)} + containerEnvVariables = append(containerEnvVariables, eventEnv, inAppLoggingEnv) workflowMainContainer := v12.Container{ Env: containerEnvVariables, Name: common.MainContainerName, Image: workflowRequest.CdImage, - Args: []string{string(workflowJson)}, SecurityContext: &v12.SecurityContext{ Privileged: &privileged, }, @@ -256,7 +267,7 @@ func (impl *CdWorkflowServiceImpl) SubmitWorkflow(workflowRequest *CdWorkflowReq } UpdateContainerEnvsFromCmCs(&workflowMainContainer, workflowConfigMaps, workflowSecrets) - impl.updateBlobStorageConfig(workflowRequest, &workflowTemplate, storageConfigured) + impl.updateBlobStorageConfig(workflowRequest, &workflowTemplate, storageConfigured, ciCdTriggerEvent.CdRequest.BlobStorageLogsKey) workflowTemplate.Containers = []v12.Container{workflowMainContainer} workflowTemplate.WorkflowNamePrefix = workflowRequest.WorkflowNamePrefix workflowTemplate.WfControllerInstanceID = impl.cdConfig.WfControllerInstanceID @@ -274,12 +285,12 @@ func (impl *CdWorkflowServiceImpl) SubmitWorkflow(workflowRequest *CdWorkflowReq return workflowExecutor.ExecuteWorkflow(workflowTemplate) } -func (impl *CdWorkflowServiceImpl) updateBlobStorageConfig(workflowRequest *CdWorkflowRequest, workflowTemplate *bean3.WorkflowTemplate, storageConfigured bool) { +func (impl *CdWorkflowServiceImpl) updateBlobStorageConfig(workflowRequest *CdWorkflowRequest, workflowTemplate *bean3.WorkflowTemplate, storageConfigured bool, blobStorageKey string) { workflowTemplate.BlobStorageConfigured = storageConfigured && (impl.cdConfig.UseBlobStorageConfigInCdWorkflow || !workflowRequest.IsExtRun) workflowTemplate.BlobStorageS3Config = workflowRequest.BlobStorageS3Config workflowTemplate.AzureBlobConfig = workflowRequest.AzureBlobConfig workflowTemplate.GcpBlobConfig = workflowRequest.GcpBlobConfig - workflowTemplate.CloudStorageKey = impl.cdConfig.DefaultBuildLogsKeyPrefix + "/" + workflowRequest.WorkflowNamePrefix + workflowTemplate.CloudStorageKey = blobStorageKey } func (impl *CdWorkflowServiceImpl) getWorkflowExecutor(executorType pipelineConfig.WorkflowExecutorType) WorkflowExecutor { diff --git a/pkg/pipeline/CiConfig.go b/pkg/pipeline/CiConfig.go index a56f6037eb..212fc86aae 100644 --- a/pkg/pipeline/CiConfig.go +++ b/pkg/pipeline/CiConfig.go @@ -84,6 +84,7 @@ type CiConfig struct { BuildxPvcCachePath string `env:"BUILDX_CACHE_PATH" envDefault:"/var/lib/devtron/buildx"` UseBlobStorageConfigInCiWorkflow bool `env:"USE_BLOB_STORAGE_CONFIG_IN_CI_WORKFLOW" envDefault:"true"` BaseLogLocationPath string `env:"BASE_LOG_LOCATION_PATH" envDefault:"/home/devtron/"` + InAppLoggingEnabled bool `env:"IN_APP_LOGGING_ENABLED" envDefault:"false"` ClusterConfig *rest.Config NodeLabel map[string]string EnableBuildContext bool `env:"ENABLE_BUILD_CONTEXT" envDefault:"false"` diff --git a/pkg/pipeline/CiHandler.go b/pkg/pipeline/CiHandler.go index 8fd82d47e5..4a7f68256d 100644 --- a/pkg/pipeline/CiHandler.go +++ b/pkg/pipeline/CiHandler.go @@ -149,6 +149,7 @@ type WorkflowResponse struct { ArtifactId int `json:"artifactId"` IsArtifactUploaded bool `json:"isArtifactUploaded"` IsVirtualEnvironment bool `json:"isVirtualEnvironment"` + PodName string `json:"podName"` } type GitTriggerInfoResponse struct { @@ -828,7 +829,7 @@ func (impl *CiHandlerImpl) extractWorkfowStatus(workflowStatus v1alpha1.Workflow const CiStageFailErrorCode = 2 func (impl *CiHandlerImpl) UpdateWorkflow(workflowStatus v1alpha1.WorkflowStatus) (int, error) { - workflowName, status, podStatus, message, logLocation, podName := impl.extractWorkfowStatus(workflowStatus) + workflowName, status, podStatus, message, _, podName := impl.extractWorkfowStatus(workflowStatus) if workflowName == "" { impl.Logger.Errorw("extract workflow status, invalid wf name", "workflowName", workflowName, "status", status, "podStatus", podStatus, "message", message) return 0, errors.New("invalid wf name") @@ -866,7 +867,7 @@ func (impl *CiHandlerImpl) UpdateWorkflow(workflowStatus v1alpha1.WorkflowStatus savedWorkflow.FinishedOn = workflowStatus.FinishedAt.Time savedWorkflow.Name = workflowName //savedWorkflow.LogLocation = "/ci-pipeline/" + strconv.Itoa(savedWorkflow.CiPipelineId) + "/workflow/" + strconv.Itoa(savedWorkflow.Id) + "/logs" //TODO need to fetch from workflow object - savedWorkflow.LogLocation = logLocation + //savedWorkflow.LogLocation = logLocation // removed because we are saving log location at trigger savedWorkflow.CiArtifactLocation = ciArtifactLocation savedWorkflow.PodName = podName impl.Logger.Debugw("updating workflow ", "workflow", savedWorkflow) diff --git a/pkg/pipeline/CiService.go b/pkg/pipeline/CiService.go index 89137fb619..6947cf6ac3 100644 --- a/pkg/pipeline/CiService.go +++ b/pkg/pipeline/CiService.go @@ -144,6 +144,8 @@ func (impl *CiServiceImpl) TriggerCiPipeline(trigger Trigger) (int, error) { return 0, err } + //savedCiWf.LogLocation = impl.ciConfig.DefaultBuildLogsKeyPrefix + "/" + workflowRequest.WorkflowNamePrefix + "/main.log" + savedCiWf.LogLocation = fmt.Sprintf("%s/%s/main.log", impl.ciConfig.DefaultBuildLogsKeyPrefix, workflowRequest.WorkflowNamePrefix) err = impl.updateCiWorkflow(workflowRequest, savedCiWf) appLabels, err := impl.appCrudOperationService.GetLabelsByAppId(pipeline.AppId) diff --git a/pkg/pipeline/WorkflowDagExecutor.go b/pkg/pipeline/WorkflowDagExecutor.go index 559dc1257c..f0c939e5f0 100644 --- a/pkg/pipeline/WorkflowDagExecutor.go +++ b/pkg/pipeline/WorkflowDagExecutor.go @@ -433,6 +433,7 @@ func (impl *WorkflowDagExecutorImpl) TriggerPreStage(ctx context.Context, cdWf * Namespace: impl.cdConfig.DefaultNamespace, BlobStorageEnabled: impl.cdConfig.BlobStorageEnabled, CdWorkflowId: cdWf.Id, + LogLocation: fmt.Sprintf("%s/%s%s-%s/main.log", impl.cdConfig.DefaultBuildLogsKeyPrefix, strconv.Itoa(cdWf.Id), string(bean.CD_WORKFLOW_TYPE_PRE), pipeline.Name), AuditLog: sql.AuditLog{CreatedOn: triggeredAt, CreatedBy: 1, UpdatedOn: triggeredAt, UpdatedBy: 1}, } var env *repository2.Environment @@ -522,6 +523,7 @@ func (impl *WorkflowDagExecutorImpl) TriggerPostStage(cdWf *pipelineConfig.CdWor Namespace: impl.cdConfig.DefaultNamespace, BlobStorageEnabled: impl.cdConfig.BlobStorageEnabled, CdWorkflowId: cdWf.Id, + LogLocation: fmt.Sprintf("%s/%s%s-%s/main.log", impl.cdConfig.DefaultBuildLogsKeyPrefix, strconv.Itoa(cdWf.Id), string(bean.CD_WORKFLOW_TYPE_POST), pipeline.Name), AuditLog: sql.AuditLog{CreatedOn: triggeredAt, CreatedBy: triggeredBy, UpdatedOn: triggeredAt, UpdatedBy: triggeredBy}, } var env *repository2.Environment @@ -712,6 +714,7 @@ func (impl *WorkflowDagExecutorImpl) buildWFRequest(runner *pipelineConfig.CdWor WorkflowId: cdWf.Id, WorkflowRunnerId: runner.Id, WorkflowNamePrefix: strconv.Itoa(runner.Id) + "-" + runner.Name, + WorkflowPrefixForLog: strconv.Itoa(cdWf.Id) + string(runner.WorkflowType) + "-" + runner.Name, CdImage: impl.cdConfig.DefaultImage, CdPipelineId: cdWf.PipelineId, TriggeredBy: triggeredBy, diff --git a/pkg/pipeline/WorkflowService.go b/pkg/pipeline/WorkflowService.go index 84ad00558a..1cd7fcfd85 100644 --- a/pkg/pipeline/WorkflowService.go +++ b/pkg/pipeline/WorkflowService.go @@ -103,6 +103,8 @@ type WorkflowRequest struct { BlobStorageS3Config *blob_storage.BlobStorageS3Config `json:"blobStorageS3Config"` AzureBlobConfig *blob_storage.AzureBlobConfig `json:"azureBlobConfig"` GcpBlobConfig *blob_storage.GcpBlobConfig `json:"gcpBlobConfig"` + BlobStorageLogsKey string `json:"blobStorageLogsKey"` + InAppLoggingEnabled bool `json:"inAppLoggingEnabled"` DefaultAddressPoolBaseCidr string `json:"defaultAddressPoolBaseCidr"` DefaultAddressPoolSize int `json:"defaultAddressPoolSize"` PreCiSteps []*bean2.StepObject `json:"preCiSteps"` @@ -216,6 +218,8 @@ func (impl *WorkflowServiceImpl) SubmitWorkflow(workflowRequest *WorkflowRequest CiRequest: workflowRequest, } + ciCdTriggerEvent.CiRequest.BlobStorageLogsKey = fmt.Sprintf("%s/%s", impl.ciConfig.DefaultBuildLogsKeyPrefix, workflowRequest.WorkflowNamePrefix) + ciCdTriggerEvent.CiRequest.InAppLoggingEnabled = impl.ciConfig.InAppLoggingEnabled workflowJson, err := json.Marshal(&ciCdTriggerEvent) if err != nil { impl.Logger.Errorw("err", err) @@ -231,7 +235,7 @@ func (impl *WorkflowServiceImpl) SubmitWorkflow(workflowRequest *WorkflowRequest privileged := true blobStorageConfigured := workflowRequest.BlobStorageConfigured - archiveLogs := blobStorageConfigured + archiveLogs := blobStorageConfigured && !impl.ciConfig.InAppLoggingEnabled limitCpu := impl.ciConfig.LimitCpu limitMem := impl.ciConfig.LimitMem @@ -276,12 +280,14 @@ func (impl *WorkflowServiceImpl) SubmitWorkflow(workflowRequest *WorkflowRequest Steps: steps, }) + eventEnv := v12.EnvVar{Name: "CI_CD_EVENT", Value: string(workflowJson)} + inAppLoggingEnv := v12.EnvVar{Name: "IN_APP_LOGGING", Value: strconv.FormatBool(impl.ciConfig.InAppLoggingEnabled)} + containerEnvVariables = append(containerEnvVariables, eventEnv, inAppLoggingEnv) ciTemplate := v1alpha1.Template{ Name: CI_WORKFLOW_NAME, Container: &v12.Container{ Env: containerEnvVariables, Image: workflowRequest.CiImage, //TODO need to check whether trigger buildx image or normal image - Args: []string{string(workflowJson)}, SecurityContext: &v12.SecurityContext{ Privileged: &privileged, },