mirror of https://github.com/1Panel-dev/1Panel
feat: 增加网站日志和错误日志
parent
6281905a55
commit
98fd2f614a
|
@ -6,6 +6,8 @@ import (
|
|||
|
||||
type WebsiteDTO struct {
|
||||
model.Website
|
||||
ErrorLogPath string `json:"errorLogPath"`
|
||||
AccessLogPath string `json:"accessLogPath"`
|
||||
}
|
||||
|
||||
type WebsitePreInstallCheck struct {
|
||||
|
|
|
@ -109,11 +109,13 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
|
|||
if err := json.Unmarshal(paramByte, &authParam); err != nil {
|
||||
return err
|
||||
}
|
||||
authByte, err := json.Marshal(authParam)
|
||||
if err != nil {
|
||||
return err
|
||||
if authParam.RootPassword != "" {
|
||||
authByte, err := json.Marshal(authParam)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appInstall.Param = string(authByte)
|
||||
}
|
||||
appInstall.Param = string(authByte)
|
||||
}
|
||||
if app.Type == "website" {
|
||||
paramByte, err := json.Marshal(params)
|
||||
|
|
|
@ -252,6 +252,14 @@ func (w WebsiteService) GetWebsite(id uint) (response.WebsiteDTO, error) {
|
|||
return res, err
|
||||
}
|
||||
res.Website = website
|
||||
|
||||
nginxInstall, err := getAppInstallByKey(constant.AppNginx)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
sitePath := path.Join(constant.AppInstallDir, constant.AppNginx, nginxInstall.Name, "www", "sites", website.Alias)
|
||||
res.ErrorLogPath = path.Join(sitePath, "log", "error.log")
|
||||
res.AccessLogPath = path.Join(sitePath, "log", "access.log")
|
||||
return res, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,9 @@ func createWebsiteFolder(nginxInstall model.AppInstall, website *model.Website)
|
|||
if err := fileOp.CreateFile(path.Join(siteFolder, "log", "access.log")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fileOp.CreateFile(path.Join(siteFolder, "log", "error.log")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fileOp.CreateDir(path.Join(siteFolder, "index"), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -130,6 +133,7 @@ func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, a
|
|||
siteFolder := path.Join("/www", "sites", website.Alias)
|
||||
commonFolder := path.Join("/www", "common")
|
||||
server.UpdateDirective("access_log", []string{path.Join(siteFolder, "log", "access.log")})
|
||||
server.UpdateDirective("error_log", []string{path.Join(siteFolder, "log", "error.log")})
|
||||
server.UpdateDirective("access_by_lua_file", []string{path.Join(commonFolder, "waf", "access.lua")})
|
||||
server.UpdateDirective("set", []string{"$RulePath", path.Join(siteFolder, "waf", "rules")})
|
||||
server.UpdateDirective("set", []string{"$logdir", path.Join(siteFolder, "log")})
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
var (
|
||||
DefaultDataDir = "/opt/1Panel/data"
|
||||
LogDir = "opt/1Panel/log"
|
||||
ResourceDir = path.Join(DefaultDataDir, "resource")
|
||||
AppResourceDir = path.Join(ResourceDir, "apps")
|
||||
AppInstallDir = path.Join(DefaultDataDir, "apps")
|
||||
|
|
|
@ -14,6 +14,7 @@ server {
|
|||
|
||||
|
||||
access_log /www/sites/domain/log/access.log;
|
||||
error_log /www/sites/domain/log/error.log;
|
||||
|
||||
access_by_lua_file /www/common/waf/access.lua;
|
||||
set $RulePath /www/sites/domain/waf/rules;
|
||||
|
|
|
@ -15,6 +15,11 @@ export namespace Website {
|
|||
webSiteSSL: SSL;
|
||||
}
|
||||
|
||||
export interface WebsiteDTO extends Website {
|
||||
errorLogPath: string;
|
||||
accessLogPath: string;
|
||||
}
|
||||
|
||||
export interface NewAppInstall {
|
||||
name: string;
|
||||
appDetailId: number;
|
||||
|
|
|
@ -28,7 +28,7 @@ export const UpdateWebsite = (req: Website.WebSiteUpdateReq) => {
|
|||
};
|
||||
|
||||
export const GetWebsite = (id: number) => {
|
||||
return http.get<Website.Website>(`/websites/${id}`);
|
||||
return http.get<Website.WebsiteDTO>(`/websites/${id}`);
|
||||
};
|
||||
|
||||
export const GetWebsiteOptions = () => {
|
||||
|
|
|
@ -867,7 +867,7 @@ export default {
|
|||
nginxConfig: 'Nginx配置',
|
||||
websiteConfig: '网站设置',
|
||||
basic: '基本',
|
||||
source: '源文',
|
||||
source: '配置文件',
|
||||
security: '安全',
|
||||
backup: '备份',
|
||||
log: '日志',
|
||||
|
@ -894,7 +894,7 @@ export default {
|
|||
forceDeleteHelper: '强制删除,会忽略删除过程中产生的错误并最终删除元数据',
|
||||
deleteAppHelper: '同时删除关联应用以及应用备份',
|
||||
deleteBackupHelper: '同时删除网站备份',
|
||||
deleteConfirmHelper: '删除操作无法回滚,请输入 <span style="color:red"> "{0}" </span> 删除此网站',
|
||||
deleteConfirmHelper: '删除操作无法回滚,请输入 <span style="color:red"> "{0}" </span> 删除',
|
||||
staticPath: '对应主目录:',
|
||||
limit: '限制方案',
|
||||
blog: '论坛/博客',
|
||||
|
@ -904,6 +904,8 @@ export default {
|
|||
doorSite: '门户',
|
||||
qiteSite: '企业',
|
||||
videoSite: '视频',
|
||||
errLog: '错误日志',
|
||||
accessLog: '网站日志',
|
||||
},
|
||||
nginx: {
|
||||
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
||||
|
|
|
@ -39,7 +39,6 @@ const acceptParams = async (params: InfoProps): Promise<void> => {
|
|||
props.value = params;
|
||||
GetFileContent({ path: params.path, expand: false, page: 1, pageSize: 1 }).then((res) => {
|
||||
data.value = res.data;
|
||||
console.log(data.value);
|
||||
open.value = true;
|
||||
});
|
||||
};
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
<el-tab-pane :label="$t('website.security')" name="safety">
|
||||
<Safety :key="id" :id="id" v-if="index === 'safety'"></Safety>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('website.log')" name="log">
|
||||
<Log :key="id" :id="id" v-if="index === 'log'"></Log>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('website.source')" name="resource">
|
||||
<Resource :key="id" :id="id" v-if="index === 'resource'"></Resource>
|
||||
</el-tab-pane>
|
||||
|
@ -22,6 +25,7 @@ import { onMounted, ref } from 'vue';
|
|||
import Basic from './basic/index.vue';
|
||||
import Safety from './safety/index.vue';
|
||||
import Resource from './resource/index.vue';
|
||||
import Log from './log/index.vue';
|
||||
import router from '@/routers';
|
||||
|
||||
const props = defineProps({
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<el-tabs tab-position="left" type="border-card" v-model="index">
|
||||
<el-tab-pane :label="$t('website.accessLog')" name="0">
|
||||
<LogFile :path="website.accessLogPath" v-if="index == '0'"></LogFile>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('website.errLog')" name="1">
|
||||
<LogFile :path="website.errorLogPath" v-if="index == '1'"></LogFile>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { GetWebsite } from '@/api/modules/website';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import LogFile from './log-fiile/index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
const id = computed(() => {
|
||||
return props.id;
|
||||
});
|
||||
|
||||
let loading = ref(false);
|
||||
let website = ref();
|
||||
let index = ref('-1');
|
||||
|
||||
const getWebsite = () => {
|
||||
loading.value = true;
|
||||
GetWebsite(id.value)
|
||||
.then((res) => {
|
||||
website.value = res.data;
|
||||
index.value = '0';
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getWebsite();
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div v-loading="loading">
|
||||
<codemirror
|
||||
:autofocus="true"
|
||||
placeholder="None data"
|
||||
:indent-with-tab="true"
|
||||
:tabSize="4"
|
||||
style="margin-top: 10px; max-height: 500px"
|
||||
:lineWrapping="true"
|
||||
:matchBrackets="true"
|
||||
theme="cobalt"
|
||||
:styleActiveLine="true"
|
||||
:extensions="extensions"
|
||||
v-model="content"
|
||||
:readOnly="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { Codemirror } from 'vue-codemirror';
|
||||
import { GetFileContent } from '@/api/modules/files';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
import { oneDark } from '@codemirror/theme-one-dark';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
|
||||
const extensions = [javascript(), oneDark];
|
||||
const props = defineProps({
|
||||
path: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
const path = computed(() => {
|
||||
return props.path;
|
||||
});
|
||||
let loading = ref(false);
|
||||
let content = ref('');
|
||||
|
||||
const getContent = () => {
|
||||
loading.value = true;
|
||||
GetFileContent({ path: path.value, expand: false, page: 1, pageSize: 1 })
|
||||
.then((res) => {
|
||||
content.value = res.data.content;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getContent();
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue