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