From 475ad2bd017669c6b7127891ba981406d9d45df3 Mon Sep 17 00:00:00 2001 From: tiga <68499559+SheepSheepChen@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:26:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=8E=B7=E5=8F=96=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E6=97=A5=E5=BF=97=20(#1691)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/devsandbox/webserver/params.go | 26 +++++ .../internal/devsandbox/webserver/server.go | 22 ++++ .../devsandbox/webserver/service/app_logs.go | 107 ++++++++++++++++++ .../webserver/service/app_logs_test.go | 72 ++++++++++++ .../webserver/service/deploy_test.go | 7 +- .../service/testdata/django-helloworld.zip | Bin 7818 -> 0 bytes .../webserver/service/testdata/helloworld.zip | Bin 7618 -> 5759 bytes .../service/testdata/helloworld/app_desc.yaml | 8 ++ .../helloworld/helloworld/__init__.py | 0 .../helloworld/helloworld/asgi.py | 0 .../helloworld/helloworld/settings.py | 0 .../helloworld/helloworld/urls.py | 0 .../helloworld/helloworld/wsgi.py | 0 .../{templates => }/helloworld/manage.py | 0 14 files changed, 239 insertions(+), 3 deletions(-) create mode 100644 cnb-builder-shim/internal/devsandbox/webserver/params.go create mode 100644 cnb-builder-shim/internal/devsandbox/webserver/service/app_logs.go create mode 100644 cnb-builder-shim/internal/devsandbox/webserver/service/app_logs_test.go delete mode 100644 cnb-builder-shim/internal/devsandbox/webserver/service/testdata/django-helloworld.zip create mode 100644 cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/app_desc.yaml rename cnb-builder-shim/internal/devsandbox/webserver/service/testdata/{templates => }/helloworld/helloworld/__init__.py (100%) rename cnb-builder-shim/internal/devsandbox/webserver/service/testdata/{templates => }/helloworld/helloworld/asgi.py (100%) rename cnb-builder-shim/internal/devsandbox/webserver/service/testdata/{templates => }/helloworld/helloworld/settings.py (100%) rename cnb-builder-shim/internal/devsandbox/webserver/service/testdata/{templates => }/helloworld/helloworld/urls.py (100%) rename cnb-builder-shim/internal/devsandbox/webserver/service/testdata/{templates => }/helloworld/helloworld/wsgi.py (100%) rename cnb-builder-shim/internal/devsandbox/webserver/service/testdata/{templates => }/helloworld/manage.py (100%) diff --git a/cnb-builder-shim/internal/devsandbox/webserver/params.go b/cnb-builder-shim/internal/devsandbox/webserver/params.go new file mode 100644 index 0000000000..9ae6aab999 --- /dev/null +++ b/cnb-builder-shim/internal/devsandbox/webserver/params.go @@ -0,0 +1,26 @@ +/* + * TencentBlueKing is pleased to support the open source community by making + * 蓝鲸智云 - PaaS 平台 (BlueKing - PaaS System) available. + * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://opensource.org/licenses/MIT + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + * We undertake not to change the open source license (MIT license) applicable + * to the current version of the project delivered to anyone in the future. + */ + +package webserver + +// LogQueryParams : log query params +// It includes the following fields: +// - lines: Specifies the number of log lines to retrieve +type LogQueryParams struct { + Lines int `form:"lines,default=100" binding:"omitempty,gte=1,lte=200"` +} diff --git a/cnb-builder-shim/internal/devsandbox/webserver/server.go b/cnb-builder-shim/internal/devsandbox/webserver/server.go index 4f6b81ce77..96e7519659 100644 --- a/cnb-builder-shim/internal/devsandbox/webserver/server.go +++ b/cnb-builder-shim/internal/devsandbox/webserver/server.go @@ -86,6 +86,7 @@ func New(lg *logr.Logger) (*WebServer, error) { mgr := service.NewDeployManager() r.POST("/deploys", DeployHandler(s, mgr)) r.GET("/deploys/:deployID/results", ResultHandler(mgr)) + r.GET("/app_logs", AppLogHandler()) return s, nil } @@ -208,4 +209,25 @@ func ResultHandler(svc service.DeployServiceHandler) gin.HandlerFunc { } } +// AppLogHandler 获取 app 日志 +func AppLogHandler() gin.HandlerFunc { + return func(c *gin.Context) { + var queryParams LogQueryParams + if err := c.ShouldBindQuery(&queryParams); err != nil { + // 验证失败 + c.JSON(http.StatusBadRequest, gin.H{ + "message": "查询参数无效,lines 必须是 1 到 200 之间的整数", + }) + return + } + // 读取日志 + logs, err := service.GetAppLogs(service.DefaultAppLogDir, queryParams.Lines) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": fmt.Sprintf("get app log error: %s", err.Error())}) + return + } + c.JSON(http.StatusOK, gin.H{"logs": logs}) + } +} + var _ devsandbox.DevWatchServer = (*WebServer)(nil) diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/app_logs.go b/cnb-builder-shim/internal/devsandbox/webserver/service/app_logs.go new file mode 100644 index 0000000000..62b952d397 --- /dev/null +++ b/cnb-builder-shim/internal/devsandbox/webserver/service/app_logs.go @@ -0,0 +1,107 @@ +/* + * TencentBlueKing is pleased to support the open source community by making + * 蓝鲸智云 - PaaS 平台 (BlueKing - PaaS System) available. + * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://opensource.org/licenses/MIT + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + * We undertake not to change the open source license (MIT license) applicable + * to the current version of the project delivered to anyone in the future. + */ + +package service + +import ( + "os" + "path/filepath" + "strings" + + "github.com/docker/docker/pkg/tailfile" +) + +// DefaultAppLogDir 应用日志默认目录 +var DefaultAppLogDir = "/cnb/devsandbox/supervisor/log" + +// GetAppLogs 获取应用日志 +// Parameters: +// - logPath: 日志路径 +// - lines: 需要的日志行数 +// +// Returns: +// - map[string][]string: key 为日志类型, value 为日志内容 +func GetAppLogs(logDir string, lines int) (map[string][]string, error) { + // 检查文件是否存在 + if _, err := os.Stat(logDir); os.IsNotExist(err) { + // 文件不存在,返回 nil, nil + return nil, nil + } + logs := make(map[string][]string) + logFiles, err := getLogFiles(logDir) + if err != nil { + return nil, err + } + for logType, file := range logFiles { + logPath := filepath.Join(logDir, file.Name()) + logLines, err := tailFile(logPath, lines) + if err != nil { + return nil, err + } + logs[logType] = logLines + } + return logs, nil +} + +// 按日志类型分类日志文件 +func getLogFiles(logDir string) (map[string]os.FileInfo, error) { + logFiles := make(map[string]os.FileInfo) + err := filepath.Walk(logDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + // 获取日志类型 + logType := getLogType(info) + if logType != "" { + logFiles[logType] = info + } + return nil + }) + if err != nil { + return nil, err + } + return logFiles, nil +} + +// 通过文件名称获取日志类型, 需要符合格式:{{type}}.log +func getLogType(info os.FileInfo) string { + if !info.IsDir() && strings.HasSuffix(strings.ToLower(info.Name()), ".log") { + logType := strings.TrimSuffix(strings.ToLower(info.Name()), filepath.Ext(info.Name())) + return logType + } + return "" +} + +// 获取文件最新部分的内容 +func tailFile(filePath string, lines int) (logs []string, err error) { + file, err := os.Open(filePath) + if err != nil { + return nil, err + } + tailBytes, err := tailfile.TailFile(file, lines) + if err != nil { + return nil, err + } + tailStr := make([]string, len(tailBytes)) + for index, b := range tailBytes { + tailStr[index] = string(b) + } + + logs = append(logs, tailStr...) + return logs, nil +} diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/app_logs_test.go b/cnb-builder-shim/internal/devsandbox/webserver/service/app_logs_test.go new file mode 100644 index 0000000000..493188fd12 --- /dev/null +++ b/cnb-builder-shim/internal/devsandbox/webserver/service/app_logs_test.go @@ -0,0 +1,72 @@ +/* + * TencentBlueKing is pleased to support the open source community by making + * 蓝鲸智云 - PaaS 平台 (BlueKing - PaaS System) available. + * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://opensource.org/licenses/MIT + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + * We undertake not to change the open source license (MIT license) applicable + * to the current version of the project delivered to anyone in the future. + */ + +package service + +import ( + "os" + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Test GetAppLogs", func() { + var err error + var logPath string + var celeryLogPath string + var mysqlLogPath string + BeforeEach(func() { + logPath, err = os.MkdirTemp("", "log_test") + Expect(err).To(BeNil()) + celeryLogPath = filepath.Join(logPath, "celery.log") + mysqlLogPath = filepath.Join(logPath, "mysql.log") + logContent1 := "value1\nvalue2\n" + logContent2 := "value3\nvalue4\n" + err := os.WriteFile(celeryLogPath, []byte(logContent1), 0644) + Expect(err).To(BeNil()) + err = os.WriteFile(mysqlLogPath, []byte(logContent2), 0644) + Expect(err).To(BeNil()) + }) + AfterEach(func() { + Expect(os.RemoveAll(logPath)).To(BeNil()) + }) + Describe("Test GetAppLogs", func() { + It("test lines < logs", func() { + logs, err := GetAppLogs(logPath, 1) + Expect(err).To(BeNil()) + Expect(len(logs["celery"])).To(Equal(1)) + Expect(logs["celery"]).To(Equal([]string{"value2"})) + Expect(len(logs["mysql"])).To(Equal(1)) + Expect(logs["mysql"]).To(Equal([]string{"value4"})) + }) + It("test lines > logs", func() { + logs, err := GetAppLogs(logPath, 5) + Expect(err).To(BeNil()) + Expect(len(logs["celery"])).To(Equal(2)) + Expect(logs["celery"]).To(Equal([]string{"value1", "value2"})) + Expect(len(logs["mysql"])).To(Equal(2)) + Expect(logs["mysql"]).To(Equal([]string{"value3", "value4"})) + }) + It("logFile does not exist", func() { + logs, err := GetAppLogs("", 5) + Expect(err).To(BeNil()) + Expect(logs).To(BeNil()) + }) + }) +}) diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/deploy_test.go b/cnb-builder-shim/internal/devsandbox/webserver/service/deploy_test.go index 3994b02f4a..24897e9051 100644 --- a/cnb-builder-shim/internal/devsandbox/webserver/service/deploy_test.go +++ b/cnb-builder-shim/internal/devsandbox/webserver/service/deploy_test.go @@ -34,7 +34,7 @@ var _ = Describe("Test DeployManager", func() { var m *DeployManager var tmpAppDir string - testSrcFilePath := filepath.Join("testdata", "templates", "django-helloworld") + testSrcFilePath := filepath.Join("testdata", "helloworld") oldAppDir := devsandbox.DefaultAppDir BeforeEach(func() { @@ -55,12 +55,13 @@ var _ = Describe("Test DeployManager", func() { Describe("Test deploy", func() { It("test deploy", func() { - result, _ := m.Deploy(testSrcFilePath) + result, err := m.Deploy(testSrcFilePath) + Expect(err).To(BeNil()) Expect(len(result.DeployID)).To(Equal(32)) Expect(result.Status).To(Equal(devsandbox.ReloadProcessing)) - _, err := os.Stat(path.Join(devsandbox.DefaultAppDir, "Procfile")) + _, err = os.Stat(path.Join(devsandbox.DefaultAppDir, "Procfile")) Expect(err).To(BeNil()) // 验证隐藏目录不会被覆盖(删除) diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/django-helloworld.zip b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/django-helloworld.zip deleted file mode 100644 index 2546dec1926a85bcc190959b75c79099dace87e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7818 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 diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld.zip b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld.zip index 6074c828cae1d2cfe09081cb9bdd1e09f2e198f1..6e1172daa7b6502522fb172ba8bb43ce3ac16850 100644 GIT binary patch delta 1592 zcmX?P{a=SSz?+#xgaHJ!J7XvEDsnq7Q%Hy6$pws3%pl<~ZMd-Pa)rs~7_}yDYhdP^ zA2ZpKQHT3YwR}1hgLO>qjGY|Fq*c$hTp@i@l3Y57F0J5ZU}X8q$iM)$?d^1b@52Tn z2jX|V3QE1u+$6s6L1@}srH<)VUmy6+dEuD4ZClnxv*for$vkD(_#a>Oe{}ug^>3QL z7q3{(dv<+G{HEx~-- zzO!)B3P;29e###f-!O@v5frd|S@)h3=|3yqx~Xiv(H9+fHE-Usbay9~bJcgt`fBx8 zzAm;_>dCeLGApv-ebtR8Z;tTCP7HC?E~#I9d7pI5fd#C4} zcFI1_nrK;$YxlnB2)2J2{xelp7TLz(fPWpoBAdFN`U zH5>4-yx)^_)RyCG%crh?3`-9-tvJ&6Xo=|l`~`bM_eI>BJJEFF{P-!R9MN}nX?WM) zJy~|(UB%iw)$ZScW)I7P<~wUuEps?!l78!?=GoaNE-&&A7ra>bxUEE?&2+buLEBLl zzpY>HdUmOY{_4E<<%eFw^cxS3J~}@|Tl?uZjbjg`ta~s2U<8GQSMhpi~3{OBy{{7>G_&ARFC4 zv2=r9{aH0IErVhS*`042%~?^5%T3HnOi$G-s01fZQ0WH^Nsv*TAfrr_jhAsxejp>t zEW*w(*+Ecz@*Z{`AhZzJm zUn{auQK0!pw`2!XpQ55;fSSi~9))La!G}5o#C^}5zv``{al-Sew#F%a@3Y=#y!}!W zQj!vGZ43WUm^?w1A;6oRV}g9o`Y@;)AYSBP;9z(QbagMIR(&4O)svtuFRkEaU}X8q z$iM&&hqu#DdmVNVad^MvqMweF7*{OYooQ05MUMFPls>%HrMK$Jktt>tXQ!B%dT5rc zm4AFq|6_T{q&r@3k{_;eeSYBS6GQWpHZx8#Fl=nU$JoHfAQGf4rPGphX5oTRL6u6j zb`KYMiHiE}`Kpn|kM`Ye;@jdfe`C)7Sc88LjNUm}S@^k5u@|1Sr`0mgC|W@@)4OOx)>cy2|wHql^&Cb<=v3FUw5txmaI#ROER3)sGR2cUS*b zpMKW;8t)J9s9dKF|85(<{kUsQp8wan0~HtAQr0xH#TF*zF)Wr3526OI0^_7K} zly>}7_>tCREwX4a@0PF8tF^pU{ z!{Qf`m?q1yn1U0m3#%45!Onw3{pL#6rHs5NDR%NcW?9MH#Jt4xRK0>qc)|o}plQMc zWhX^;V-(lLv+FY|L;Qu}MqsMeK+aW@6Zym>_2LtY(=+MhW-ef0GcbVMJe|WF>}F{0 zoqUr+OBUU+I_Qp-)r*gh&&Q%g!R^U{lv zT}+o`5x|FVUQ2WP2fr$sdGSK(*lH--4EKIbcEs%E^F>l{g_Q zuzz8-CRC3C$eYOZ5U4JMfwzqfjFTOOC8TgygD|@lfVEa6a(O3$WX_UC7pBSgg{0v{ z9+IQM8o4_TSeOEBtpH+q6pd~yKnJM7H9~v@_N^PpZ9K{b3JBb#E-W0tVI3(V&D6m@`Jsr!wx+T< z513s30h5a?ir16{L2ePpRvh6=B&gB$M+oL7U{#0BD5T^IPAI%$(o83W!J&X&9^ncF iR2%I@VK&<9#p5WAFcS(Z8z@eNfN&u@0|U1hhz9_JN~1IY diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/app_desc.yaml b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/app_desc.yaml new file mode 100644 index 0000000000..b2b8c8ffdd --- /dev/null +++ b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/app_desc.yaml @@ -0,0 +1,8 @@ +spec_version: 2 +module: + language: Python + scripts: + pre_release_hook: "python manage.py migrate --no-input" + processes: + web: + command: python manage.py runserver 0.0.0.0:8080 \ No newline at end of file diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/__init__.py b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/__init__.py similarity index 100% rename from cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/__init__.py rename to cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/__init__.py diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/asgi.py b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/asgi.py similarity index 100% rename from cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/asgi.py rename to cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/asgi.py diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/settings.py b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/settings.py similarity index 100% rename from cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/settings.py rename to cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/settings.py diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/urls.py b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/urls.py similarity index 100% rename from cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/urls.py rename to cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/urls.py diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/wsgi.py b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/wsgi.py similarity index 100% rename from cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/helloworld/wsgi.py rename to cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/helloworld/wsgi.py diff --git a/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/manage.py b/cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/manage.py similarity index 100% rename from cnb-builder-shim/internal/devsandbox/webserver/service/testdata/templates/helloworld/manage.py rename to cnb-builder-shim/internal/devsandbox/webserver/service/testdata/helloworld/manage.py