mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 18:19:02 +00:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
047d59381c | ||
|
|
cdb4219065 | ||
|
|
5e69f4dfd0 | ||
|
|
aeb0083394 | ||
|
|
cabe8d8ff9 | ||
|
|
02f635bdd3 | ||
|
|
4ac8170d21 | ||
|
|
5641a5ca89 | ||
|
|
de8bd79ef9 | ||
|
|
30332969ee |
+12
-16
@@ -18,8 +18,11 @@
|
||||
package org.apache.hertzbeat.warehouse.store;
|
||||
|
||||
import java.util.Optional;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hertzbeat.common.constants.CommonConstants;
|
||||
import org.apache.hertzbeat.common.entity.manager.Monitor;
|
||||
import org.apache.hertzbeat.common.entity.message.CollectRep;
|
||||
import org.apache.hertzbeat.common.queue.CommonDataQueue;
|
||||
import org.apache.hertzbeat.plugin.PostCollectPlugin;
|
||||
@@ -27,7 +30,6 @@ import org.apache.hertzbeat.plugin.runner.PluginRunner;
|
||||
import org.apache.hertzbeat.warehouse.WarehouseWorkerPool;
|
||||
import org.apache.hertzbeat.warehouse.store.history.HistoryDataWriter;
|
||||
import org.apache.hertzbeat.warehouse.store.realtime.RealTimeDataWriter;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -44,6 +46,8 @@ public class DataStorageDispatch {
|
||||
private final RealTimeDataWriter realTimeDataWriter;
|
||||
private final Optional<HistoryDataWriter> historyDataWriter;
|
||||
private final PluginRunner pluginRunner;
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
public DataStorageDispatch(CommonDataQueue commonDataQueue,
|
||||
WarehouseWorkerPool workerPool,
|
||||
@@ -87,24 +91,16 @@ public class DataStorageDispatch {
|
||||
if (metricsData.getPriority() == 0) {
|
||||
long id = metricsData.getId();
|
||||
CollectRep.Code code = metricsData.getCode();
|
||||
// query current status
|
||||
String queryStatusSql = "SELECT status FROM hzb_monitor WHERE id = ?";
|
||||
try {
|
||||
int currentStatus = jdbcTemplate.queryForObject(queryStatusSql, Integer.class, id);
|
||||
if (code == CollectRep.Code.SUCCESS && currentStatus == CommonConstants.MONITOR_DOWN_CODE) {
|
||||
// if collect success and current status is DOWN, update to UP
|
||||
String sql = "UPDATE hzb_monitor SET status = ? WHERE id = ?";
|
||||
jdbcTemplate.update(sql, CommonConstants.MONITOR_UP_CODE, id);
|
||||
} else if (code != CollectRep.Code.SUCCESS && currentStatus == CommonConstants.MONITOR_UP_CODE) {
|
||||
// if collect failed and current status is UP, update to DOWN
|
||||
String sql = "UPDATE hzb_monitor SET status = ? WHERE id = ?";
|
||||
jdbcTemplate.update(sql, CommonConstants.MONITOR_DOWN_CODE, id);
|
||||
String sql = "UPDATE hzb_monitor SET status = ? WHERE id = ? AND status != ?";
|
||||
int status = code == CollectRep.Code.SUCCESS ? CommonConstants.MONITOR_UP_CODE : CommonConstants.MONITOR_DOWN_CODE;
|
||||
int matchedRows = jdbcTemplate.update(sql, status, id, status);
|
||||
if (matchedRows > 0) {
|
||||
entityManager.getEntityManagerFactory().getCache().evict(Monitor.class, id);
|
||||
}
|
||||
} catch (EmptyResultDataAccessException ignored) {
|
||||
// when query currentStatus result is null
|
||||
} catch (Exception e) {
|
||||
log.error("Update monitor status failed for monitor id: {}", id, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ export class AppComponent implements OnInit {
|
||||
private router: Router,
|
||||
private titleSrv: TitleService,
|
||||
private modalSrv: NzModalService,
|
||||
private themeService: ThemeService,
|
||||
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
|
||||
) {
|
||||
renderer.setAttribute(el.nativeElement, 'ng-alain-version', VERSION_ALAIN.full);
|
||||
@@ -49,10 +48,5 @@ export class AppComponent implements OnInit {
|
||||
this.modalSrv.closeAll();
|
||||
}
|
||||
});
|
||||
// set theme
|
||||
const storedTheme = localStorage.getItem('theme');
|
||||
if (storedTheme) {
|
||||
this.themeService.changeTheme(storedTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { catchError, map } from 'rxjs/operators';
|
||||
import { ICONS } from '../../../style-icons';
|
||||
import { ICONS_AUTO } from '../../../style-icons-auto';
|
||||
import { MemoryStorageService } from '../../service/memory-storage.service';
|
||||
import { ThemeService } from '../../service/theme.service';
|
||||
import { I18NService } from '../i18n/i18n.service';
|
||||
|
||||
@Injectable({
|
||||
@@ -28,7 +29,8 @@ export class StartupService {
|
||||
@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
|
||||
private httpClient: HttpClient,
|
||||
private router: Router,
|
||||
private storageService: MemoryStorageService
|
||||
private storageService: MemoryStorageService,
|
||||
private themeService: ThemeService
|
||||
) {
|
||||
iconSrv.addIcon(...ICONS_AUTO, ...ICONS);
|
||||
}
|
||||
@@ -86,6 +88,7 @@ export class StartupService {
|
||||
this.storageService.putData('hierarchy', menuData.data);
|
||||
this.menuService.resume();
|
||||
this.titleService.suffix = appData.app.name;
|
||||
this.themeService.changeTheme(null);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,9 +41,6 @@ import { CONSTANTS } from '../../shared/constants';
|
||||
<div nz-menu-item>
|
||||
<header-fullscreen></header-fullscreen>
|
||||
</div>
|
||||
<div nz-menu-item>
|
||||
<header-clear-storage></header-clear-storage>
|
||||
</div>
|
||||
<div nz-menu-item routerLink="/setting/labels">
|
||||
<i nz-icon nzType="tag" class="mr-sm"></i>
|
||||
<span style="margin-left: 4px">{{ 'menu.advanced.labels' | i18n }}</span>
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component, HostListener, Inject } from '@angular/core';
|
||||
import { I18NService } from '@core';
|
||||
import { ALAIN_I18N_TOKEN } from '@delon/theme';
|
||||
import { NzMessageService } from 'ng-zorro-antd/message';
|
||||
import { NzModalService } from 'ng-zorro-antd/modal';
|
||||
|
||||
@Component({
|
||||
selector: 'header-clear-storage',
|
||||
template: `
|
||||
<i nz-icon class="mr-sm" nzType="tool"></i>
|
||||
{{ 'menu.clear.local.storage' | i18n }}
|
||||
`,
|
||||
host: {
|
||||
'[class.d-block]': 'true'
|
||||
},
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class HeaderClearStorageComponent {
|
||||
constructor(
|
||||
private modalSrv: NzModalService,
|
||||
private messageSrv: NzMessageService,
|
||||
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService
|
||||
) {}
|
||||
|
||||
@HostListener('click')
|
||||
_click(): void {
|
||||
this.modalSrv.confirm({
|
||||
nzTitle: this.i18nSvc.fanyi('common.confirm.clear-cache'),
|
||||
nzOnOk: () => {
|
||||
localStorage.clear();
|
||||
this.messageSrv.success(this.i18nSvc.fanyi('common.notify.clear-success'));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -129,12 +129,7 @@ export class HeaderUserComponent {
|
||||
}
|
||||
|
||||
logout(): void {
|
||||
let tmp = this.localStorageSvc.getData(this.notShowAgainKey);
|
||||
if (tmp === null) {
|
||||
tmp = 'false';
|
||||
}
|
||||
this.localStorageSvc.clear();
|
||||
this.localStorageSvc.putData(this.notShowAgainKey, tmp);
|
||||
this.localStorageSvc.clearAuthorization();
|
||||
this.router.navigateByUrl('/passport/login');
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import { NzInputModule } from 'ng-zorro-antd/input';
|
||||
import { NzSpinModule } from 'ng-zorro-antd/spin';
|
||||
|
||||
import { LayoutBasicComponent } from './basic/basic.component';
|
||||
import { HeaderClearStorageComponent } from './basic/widgets/clear-storage.component';
|
||||
import { HeaderFullScreenComponent } from './basic/widgets/fullscreen.component';
|
||||
import { HeaderI18nComponent } from './basic/widgets/i18n.component';
|
||||
import { HeaderSearchComponent } from './basic/widgets/search.component';
|
||||
@@ -33,7 +32,6 @@ const HEADER_COMPONENTS = [
|
||||
HeaderSearchComponent,
|
||||
HeaderFullScreenComponent,
|
||||
HeaderI18nComponent,
|
||||
HeaderClearStorageComponent,
|
||||
HeaderUserComponent,
|
||||
HeaderNotifyComponent
|
||||
];
|
||||
|
||||
@@ -67,17 +67,50 @@
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
transform-style: preserve-3d;
|
||||
perspective: 1200px;
|
||||
}
|
||||
|
||||
:root {
|
||||
--background-color: #fff;
|
||||
--text-color: #333;
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
--background-color: #1e1e1e;
|
||||
--text-color: #fff;
|
||||
}
|
||||
|
||||
.alert-card {
|
||||
background: #fff;
|
||||
position: relative;
|
||||
background: var(--background-color);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
border-left: 4px solid #ff4d4f;
|
||||
transition: all 0.3s;
|
||||
z-index: 1;
|
||||
|
||||
&.expanded {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&.status-firing {
|
||||
border-left: 4px solid #ff4d4f;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&.status-resolved {
|
||||
border-left: 4px solid #52c41a;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
&.status-pending {
|
||||
border-left: 4px solid #faad14;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.15);
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
::ng-deep .ant-card-body {
|
||||
@@ -89,7 +122,7 @@
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
|
||||
.alert-info {
|
||||
flex: 1;
|
||||
@@ -109,7 +142,7 @@
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-top: 8px;
|
||||
color: #8c8c8c;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
font-size: 12px;
|
||||
|
||||
i {
|
||||
@@ -142,16 +175,22 @@
|
||||
|
||||
.alert-details {
|
||||
margin-top: 12px;
|
||||
position: relative;
|
||||
z-index: 4;
|
||||
|
||||
::ng-deep {
|
||||
.ant-collapse {
|
||||
background: transparent;
|
||||
border: none;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
|
||||
.ant-collapse-item {
|
||||
border-radius: 2px;
|
||||
border: 1px solid #f0f0f0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 8px;
|
||||
position: relative;
|
||||
z-index: 6;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
@@ -161,9 +200,11 @@
|
||||
padding: 8px 12px;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
z-index: 7;
|
||||
|
||||
&:hover {
|
||||
background-color: #fafafa;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.ant-collapse-header-text {
|
||||
@@ -172,19 +213,21 @@
|
||||
|
||||
.ant-collapse-extra {
|
||||
margin: 0;
|
||||
color: #8c8c8c;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.alert-content {
|
||||
font-size: 13px;
|
||||
color: #333;
|
||||
color: var(--text-color);
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-collapse-content {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
position: relative;
|
||||
z-index: 6;
|
||||
|
||||
.ant-collapse-content-box {
|
||||
padding: 12px;
|
||||
@@ -268,20 +311,6 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.alert-card {
|
||||
&.status-firing {
|
||||
border-left-color: #ff4d4f;
|
||||
}
|
||||
|
||||
&.status-resolved {
|
||||
border-left-color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-pending {
|
||||
border-left-color: #faad14;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInFromRight {
|
||||
0% {
|
||||
transform: translate3d(120%, 0, 0) scale(0.95) rotate(3deg);
|
||||
@@ -304,7 +333,6 @@
|
||||
}
|
||||
|
||||
.alert-card {
|
||||
position: relative;
|
||||
transition:
|
||||
transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94),
|
||||
opacity 0.5s ease-out,
|
||||
@@ -331,6 +359,7 @@
|
||||
);
|
||||
opacity: 0;
|
||||
animation: slideGlow 1s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.new-alert {
|
||||
@@ -365,7 +394,3 @@
|
||||
.alert-card:nth-child(2) { animation-delay: 0.15s; }
|
||||
.alert-card:nth-child(3) { animation-delay: 0.2s; }
|
||||
.alert-card:nth-child(n+4) { animation-delay: 0.25s; }
|
||||
|
||||
.alert-cards {
|
||||
perspective: 1200px;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,32 @@
|
||||
:root {
|
||||
--background-color: #fff;
|
||||
--text-color: #333;
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
--background-color: #1e1e1e;
|
||||
--text-color: #fff;
|
||||
}
|
||||
|
||||
.alert-integration-container {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
background: var(--background-color);
|
||||
border-radius: 4px;
|
||||
|
||||
|
||||
.data-sources {
|
||||
width: 240px;
|
||||
border-right: 1px solid #f0f0f0;
|
||||
padding: 16px;
|
||||
|
||||
background: var(--background-color);
|
||||
|
||||
h2 {
|
||||
margin-bottom: 16px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
|
||||
.source-list {
|
||||
.source-item {
|
||||
display: flex;
|
||||
@@ -23,37 +35,53 @@
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s;
|
||||
|
||||
|
||||
&:hover {
|
||||
background: #f5f5f5;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
|
||||
&.active {
|
||||
background: #e6f7ff;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
|
||||
span {
|
||||
color: #333;
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.doc-content {
|
||||
flex: 1;
|
||||
padding: 24px;
|
||||
overflow-y: auto;
|
||||
|
||||
background: var(--background-color);
|
||||
|
||||
h2 {
|
||||
margin-bottom: 24px;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
.source-list {
|
||||
.source-item {
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
~ under the License.
|
||||
-->
|
||||
|
||||
<div class="br-8" style="background-color: snow; padding: 20px; box-shadow: 7px 5px #b421cc">
|
||||
<div class="br-8" style="background-color: rgb(198 189 189 / 39%); padding: 20px; box-shadow: 7px 5px #b421cc">
|
||||
<form nz-form [formGroup]="form" (ngSubmit)="submit()" role="form">
|
||||
<nz-tabset [nzAnimated]="false" class="tabs" (nzSelectChange)="switch($event)">
|
||||
<nz-tab [nzTitle]="'app.login.tab-login-credentials' | i18n">
|
||||
|
||||
@@ -58,7 +58,7 @@ export class SystemConfigComponent implements OnInit {
|
||||
if (message.code === 0) {
|
||||
if (message.data) {
|
||||
this.config = message.data;
|
||||
this.changeTheme(this.config.theme); // update theme after config is loaded
|
||||
this.config.theme = this.themeService.getTheme() || 'default';
|
||||
} else {
|
||||
this.config = new SystemConfig();
|
||||
}
|
||||
@@ -94,6 +94,7 @@ export class SystemConfigComponent implements OnInit {
|
||||
this.i18nSvc.loadLangData(language).subscribe(res => {
|
||||
this.i18nSvc.use(language, res);
|
||||
this.settings.setLayout('lang', language);
|
||||
this.themeService.setTheme(this.config.theme);
|
||||
setTimeout(() => this.doc.location.reload());
|
||||
});
|
||||
} else {
|
||||
@@ -105,8 +106,4 @@ export class SystemConfigComponent implements OnInit {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
changeTheme(theme: string): void {
|
||||
this.themeService.changeTheme(theme);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
@import '@delon/theme/index';
|
||||
|
||||
.tag-cards-container {
|
||||
padding: 24px 0;
|
||||
|
||||
.tag-card {
|
||||
transition: all 0.3s;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
@@ -23,8 +24,7 @@
|
||||
|
||||
.ant-card-actions {
|
||||
border-radius: 0 0 8px 8px;
|
||||
background: #fafafa;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-top: 1px solid rgba(240, 240, 240, 0.5);
|
||||
min-height: 32px;
|
||||
|
||||
> li {
|
||||
@@ -34,7 +34,7 @@
|
||||
padding: 4px 0;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
i {
|
||||
@@ -60,6 +60,7 @@
|
||||
font-weight: 500;
|
||||
line-height: 1.4;
|
||||
text-align: center;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,8 @@ export class LocalStorageService {
|
||||
return localStorage.getItem(AuthorizationConst) != null;
|
||||
}
|
||||
|
||||
public clear() {
|
||||
localStorage.clear();
|
||||
public clearAuthorization() {
|
||||
localStorage.removeItem(AuthorizationConst);
|
||||
localStorage.removeItem(RefreshTokenConst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,11 +36,10 @@ export class ThemeService {
|
||||
return localStorage.getItem(this.themeKey);
|
||||
}
|
||||
|
||||
clearTheme(): void {
|
||||
localStorage.removeItem(this.themeKey);
|
||||
}
|
||||
|
||||
changeTheme(theme: string): void {
|
||||
changeTheme(theme: string | null): void {
|
||||
if (theme == null) {
|
||||
theme = this.getTheme();
|
||||
}
|
||||
const style = this.doc.createElement('link');
|
||||
style.type = 'text/css';
|
||||
style.rel = 'stylesheet';
|
||||
@@ -57,9 +56,6 @@ export class ThemeService {
|
||||
|
||||
const compactDom = this.doc.getElementById('compact-theme');
|
||||
if (compactDom) compactDom.remove();
|
||||
|
||||
this.clearTheme();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -420,6 +420,8 @@
|
||||
"common.confirm.delete-batch": "请确认是否批量删除!",
|
||||
"common.confirm.enable": "请确认是否启用!",
|
||||
"common.confirm.enable-batch": "请确认是否批量启用!",
|
||||
"common.copy": "复制到粘贴板",
|
||||
"common.copy.button": "复制",
|
||||
"common.disable": "关闭",
|
||||
"common.edit": "操作",
|
||||
"common.edit-time": "更新时间",
|
||||
|
||||
Reference in New Issue
Block a user