mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:21:10 +02:00
feat(infra): add api.mana.how route + Prometheus scrape targets for Go services
- Cloudflare Tunnel: api.mana.how → localhost:3060 (Go API Gateway) - Prometheus: scrape targets for mana-api-gateway:3060 and mana-matrix-bot:4000 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c81527c57c
commit
a31ccc6c62
11 changed files with 434 additions and 95 deletions
|
|
@ -543,6 +543,8 @@ Logged in: App → IndexedDB → UI → SyncEngine → mana-sync (Go) → Postg
|
|||
| Mukke | songs, playlists, playlistSongs, projects, markers | Done |
|
||||
| Context | spaces, documents | Done |
|
||||
| Photos | albums, albumItems, favorites, tags, photoTags | Done |
|
||||
| SkilltTree | skills, activities, achievements | Done |
|
||||
| CityCorners | locations, favorites | Done |
|
||||
|
||||
### Dev Commands (Local-First Stack)
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
"dependencies": {
|
||||
"@manacore/shared-auth": "workspace:*",
|
||||
"@manacore/shared-auth-ui": "workspace:*",
|
||||
"@manacore/local-store": "workspace:*",
|
||||
"@manacore/shared-branding": "workspace:*",
|
||||
"@manacore/shared-error-tracking": "workspace:*",
|
||||
"@manacore/shared-feedback-service": "workspace:*",
|
||||
|
|
|
|||
49
apps/citycorners/apps/web/src/lib/data/guest-seed.ts
Normal file
49
apps/citycorners/apps/web/src/lib/data/guest-seed.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Guest seed data for the CityCorners app.
|
||||
*
|
||||
* Provides iconic Konstanz locations for the onboarding experience.
|
||||
*/
|
||||
|
||||
import type { LocalLocation } from './local-store';
|
||||
|
||||
export const guestLocations: LocalLocation[] = [
|
||||
{
|
||||
id: 'loc-muenster',
|
||||
name: 'Konstanzer Münster',
|
||||
category: 'sight',
|
||||
description:
|
||||
'Das Münster Unserer Lieben Frau ist die ehemalige Bischofskirche des Bistums Konstanz und Wahrzeichen der Stadt.',
|
||||
address: 'Münsterplatz 1, 78462 Konstanz',
|
||||
latitude: 47.6603,
|
||||
longitude: 9.1752,
|
||||
},
|
||||
{
|
||||
id: 'loc-imperia',
|
||||
name: 'Imperia',
|
||||
category: 'sight',
|
||||
description:
|
||||
'Die 9 Meter hohe Statue im Hafen von Konstanz dreht sich einmal in 4 Minuten um ihre Achse.',
|
||||
address: 'Hafen, 78462 Konstanz',
|
||||
latitude: 47.6596,
|
||||
longitude: 9.1789,
|
||||
},
|
||||
{
|
||||
id: 'loc-insel',
|
||||
name: 'Mainau – Blumeninsel',
|
||||
category: 'park',
|
||||
description:
|
||||
'Die Blumeninsel Mainau im Bodensee ist bekannt für ihre Gärten, das Schmetterlingshaus und das Barockschloss.',
|
||||
address: 'Mainau 1, 78465 Konstanz',
|
||||
latitude: 47.7051,
|
||||
longitude: 9.1919,
|
||||
},
|
||||
{
|
||||
id: 'loc-strandbad',
|
||||
name: 'Strandbad Horn',
|
||||
category: 'beach',
|
||||
description: 'Beliebtes Freibad am Bodensee mit Sandstrand und Blick auf die Alpen.',
|
||||
address: 'Eichhornstraße 100, 78464 Konstanz',
|
||||
latitude: 47.6753,
|
||||
longitude: 9.2001,
|
||||
},
|
||||
];
|
||||
63
apps/citycorners/apps/web/src/lib/data/local-store.ts
Normal file
63
apps/citycorners/apps/web/src/lib/data/local-store.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* CityCorners — Local-First Data Layer
|
||||
*
|
||||
* Locations and favorites stored locally for offline browsing.
|
||||
* Location lookup and web search remain server-side.
|
||||
*/
|
||||
|
||||
import { createLocalStore, type BaseRecord } from '@manacore/local-store';
|
||||
import { guestLocations } from './guest-seed';
|
||||
|
||||
// ─── Types ──────────────────────────────────────────────────
|
||||
|
||||
export interface LocalLocation extends BaseRecord {
|
||||
name: string;
|
||||
category:
|
||||
| 'sight'
|
||||
| 'restaurant'
|
||||
| 'shop'
|
||||
| 'museum'
|
||||
| 'cafe'
|
||||
| 'bar'
|
||||
| 'park'
|
||||
| 'beach'
|
||||
| 'hotel'
|
||||
| 'event_venue'
|
||||
| 'viewpoint';
|
||||
description?: string | null;
|
||||
address?: string | null;
|
||||
latitude?: number | null;
|
||||
longitude?: number | null;
|
||||
imageUrl?: string | null;
|
||||
timeline?: Array<{ year: number; event: string }> | null;
|
||||
}
|
||||
|
||||
export interface LocalFavorite extends BaseRecord {
|
||||
locationId: string;
|
||||
}
|
||||
|
||||
// ─── Store ──────────────────────────────────────────────────
|
||||
|
||||
const SYNC_SERVER_URL = import.meta.env.PUBLIC_SYNC_SERVER_URL || 'http://localhost:3050';
|
||||
|
||||
export const citycornersStore = createLocalStore({
|
||||
appId: 'citycorners',
|
||||
collections: [
|
||||
{
|
||||
name: 'locations',
|
||||
indexes: ['category', 'name'],
|
||||
guestSeed: guestLocations,
|
||||
},
|
||||
{
|
||||
name: 'favorites',
|
||||
indexes: ['locationId'],
|
||||
},
|
||||
],
|
||||
sync: {
|
||||
serverUrl: SYNC_SERVER_URL,
|
||||
},
|
||||
});
|
||||
|
||||
// Typed collection accessors
|
||||
export const locationCollection = citycornersStore.collection<LocalLocation>('locations');
|
||||
export const favoriteCollection = citycornersStore.collection<LocalFavorite>('favorites');
|
||||
|
|
@ -9,6 +9,9 @@
|
|||
import { theme } from '$lib/stores/theme.svelte';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import { favoritesStore } from '$lib/stores/favorites.svelte';
|
||||
import { AuthGate, GuestWelcomeModal } from '@manacore/shared-auth-ui';
|
||||
import { shouldShowGuestWelcome } from '@manacore/shared-auth-ui';
|
||||
import { citycornersStore } from '$lib/data/local-store';
|
||||
import { THEME_DEFINITIONS, DEFAULT_THEME_VARIANTS } from '@manacore/shared-theme';
|
||||
import type { ThemeVariant } from '@manacore/shared-theme';
|
||||
import { getPillAppItems } from '@manacore/shared-branding';
|
||||
|
|
@ -172,109 +175,126 @@
|
|||
showNav = !showNav;
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
const savedNav = localStorage.getItem('citycorners-nav-visible');
|
||||
if (savedNav !== null) showNav = savedNav !== 'false';
|
||||
let showGuestWelcome = $state(false);
|
||||
|
||||
async function handleAuthReady() {
|
||||
await citycornersStore.initialize();
|
||||
if (authStore.isAuthenticated) {
|
||||
citycornersStore.startSync(() => authStore.getValidToken());
|
||||
await tagStore.fetchTags();
|
||||
}
|
||||
});
|
||||
if (!authStore.isAuthenticated && shouldShowGuestWelcome('citycorners')) {
|
||||
showGuestWelcome = true;
|
||||
}
|
||||
const savedNav = localStorage.getItem('citycorners-nav-visible');
|
||||
if (savedNav !== null) showNav = savedNav !== 'false';
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="layout-container">
|
||||
{#if showNav}
|
||||
<PillNavigation
|
||||
items={navItems}
|
||||
currentPath={$page.url.pathname}
|
||||
appName="CityCorners"
|
||||
homeRoute="/"
|
||||
onToggleTheme={handleToggleTheme}
|
||||
{isDark}
|
||||
showThemeToggle={true}
|
||||
showThemeVariants={true}
|
||||
{themeVariantItems}
|
||||
{currentThemeVariantLabel}
|
||||
themeMode={theme.mode}
|
||||
onThemeModeChange={handleThemeModeChange}
|
||||
showLanguageSwitcher={true}
|
||||
{languageItems}
|
||||
{currentLanguageLabel}
|
||||
showLogout={authStore.isAuthenticated}
|
||||
onLogout={handleLogout}
|
||||
loginHref="/login"
|
||||
primaryColor="#2563eb"
|
||||
showAppSwitcher={true}
|
||||
{appItems}
|
||||
{userEmail}
|
||||
settingsHref="/settings"
|
||||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
profileHref="/profile"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
{#if isTagStripVisible}
|
||||
<TagStrip
|
||||
tags={tagStore.tags.map((t) => ({
|
||||
id: t.id,
|
||||
name: t.name,
|
||||
color: t.color || '#3b82f6',
|
||||
}))}
|
||||
selectedIds={[]}
|
||||
onToggle={() => {}}
|
||||
onClear={() => {}}
|
||||
managementHref="/tags"
|
||||
loading={tagStore.loading}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<!-- Quick Search Bar -->
|
||||
<QuickInputBar
|
||||
onSearch={handleSearch}
|
||||
onSelect={handleSelect}
|
||||
placeholder={$_('search.placeholder')}
|
||||
emptyText={$_('search.noResults')}
|
||||
searchingText={$_('search.searching')}
|
||||
locale={$locale || 'de'}
|
||||
appIcon="mappin"
|
||||
bottomOffset={inputBarBottomOffset}
|
||||
hasFabRight={true}
|
||||
/>
|
||||
|
||||
<button
|
||||
class="pillnav-fab"
|
||||
onclick={handleNavToggle}
|
||||
title={showNav ? $_('nav.hideNav') : $_('nav.showNav')}
|
||||
>
|
||||
{#if !showNav}
|
||||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="fab-icon">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 6h16M4 12h16M4 18h16"
|
||||
/>
|
||||
</svg>
|
||||
{:else}
|
||||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="fab-icon">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
<AuthGate {authStore} {goto} allowGuest={true} onReady={handleAuthReady}>
|
||||
<div class="layout-container">
|
||||
{#if showNav}
|
||||
<PillNavigation
|
||||
items={navItems}
|
||||
currentPath={$page.url.pathname}
|
||||
appName="CityCorners"
|
||||
homeRoute="/"
|
||||
onToggleTheme={handleToggleTheme}
|
||||
{isDark}
|
||||
showThemeToggle={true}
|
||||
showThemeVariants={true}
|
||||
{themeVariantItems}
|
||||
{currentThemeVariantLabel}
|
||||
themeMode={theme.mode}
|
||||
onThemeModeChange={handleThemeModeChange}
|
||||
showLanguageSwitcher={true}
|
||||
{languageItems}
|
||||
{currentLanguageLabel}
|
||||
showLogout={authStore.isAuthenticated}
|
||||
onLogout={handleLogout}
|
||||
loginHref="/login"
|
||||
primaryColor="#2563eb"
|
||||
showAppSwitcher={true}
|
||||
{appItems}
|
||||
{userEmail}
|
||||
settingsHref="/settings"
|
||||
themesHref="/themes"
|
||||
helpHref="/help"
|
||||
profileHref="/profile"
|
||||
/>
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<main class="main-content bg-background">
|
||||
<div class="content-wrapper">
|
||||
{@render children()}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<!-- TagStrip (above PillNav, toggled via Tags pill) -->
|
||||
{#if isTagStripVisible}
|
||||
<TagStrip
|
||||
tags={tagStore.tags.map((t) => ({
|
||||
id: t.id,
|
||||
name: t.name,
|
||||
color: t.color || '#3b82f6',
|
||||
}))}
|
||||
selectedIds={[]}
|
||||
onToggle={() => {}}
|
||||
onClear={() => {}}
|
||||
managementHref="/tags"
|
||||
loading={tagStore.loading}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<!-- Quick Search Bar -->
|
||||
<QuickInputBar
|
||||
onSearch={handleSearch}
|
||||
onSelect={handleSelect}
|
||||
placeholder={$_('search.placeholder')}
|
||||
emptyText={$_('search.noResults')}
|
||||
searchingText={$_('search.searching')}
|
||||
locale={$locale || 'de'}
|
||||
appIcon="mappin"
|
||||
bottomOffset={inputBarBottomOffset}
|
||||
hasFabRight={true}
|
||||
/>
|
||||
|
||||
<button
|
||||
class="pillnav-fab"
|
||||
onclick={handleNavToggle}
|
||||
title={showNav ? $_('nav.hideNav') : $_('nav.showNav')}
|
||||
>
|
||||
{#if !showNav}
|
||||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="fab-icon">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 6h16M4 12h16M4 18h16"
|
||||
/>
|
||||
</svg>
|
||||
{:else}
|
||||
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" class="fab-icon">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<main class="main-content bg-background">
|
||||
<div class="content-wrapper">
|
||||
{@render children()}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<GuestWelcomeModal
|
||||
appId="citycorners"
|
||||
visible={showGuestWelcome}
|
||||
onClose={() => (showGuestWelcome = false)}
|
||||
onLogin={() => goto('/login')}
|
||||
onRegister={() => goto('/register')}
|
||||
locale={($locale || 'de') === 'de' ? 'de' : 'en'}
|
||||
/>
|
||||
</AuthGate>
|
||||
|
||||
<style>
|
||||
.layout-container {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"@manacore/shared-help-types": "workspace:*",
|
||||
"@manacore/shared-help-ui": "workspace:*",
|
||||
"@manacore/shared-icons": "workspace:*",
|
||||
"@manacore/local-store": "workspace:*",
|
||||
"@manacore/shared-app-onboarding": "workspace:*",
|
||||
"@manacore/shared-tailwind": "workspace:*",
|
||||
"@manacore/shared-theme": "workspace:*",
|
||||
|
|
|
|||
51
apps/skilltree/apps/web/src/lib/data/guest-seed.ts
Normal file
51
apps/skilltree/apps/web/src/lib/data/guest-seed.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* Guest seed data for the SkilltTree app.
|
||||
*
|
||||
* Provides a demo skill with an activity to showcase the leveling system.
|
||||
*/
|
||||
|
||||
import type { LocalSkill, LocalActivity } from './local-store';
|
||||
|
||||
const DEMO_SKILL_ID = 'demo-coding';
|
||||
|
||||
export const guestSkills: LocalSkill[] = [
|
||||
{
|
||||
id: DEMO_SKILL_ID,
|
||||
name: 'Programmieren',
|
||||
description: 'Software-Entwicklung und Coding-Skills',
|
||||
branch: 'intellect',
|
||||
icon: '💻',
|
||||
currentXp: 150,
|
||||
totalXp: 150,
|
||||
level: 1,
|
||||
},
|
||||
{
|
||||
id: 'demo-fitness',
|
||||
name: 'Fitness',
|
||||
description: 'Körperliche Fitness und Training',
|
||||
branch: 'body',
|
||||
icon: '💪',
|
||||
currentXp: 50,
|
||||
totalXp: 50,
|
||||
level: 0,
|
||||
},
|
||||
];
|
||||
|
||||
export const guestActivities: LocalActivity[] = [
|
||||
{
|
||||
id: 'activity-1',
|
||||
skillId: DEMO_SKILL_ID,
|
||||
xpEarned: 100,
|
||||
description: 'TypeScript-Projekt aufgesetzt',
|
||||
duration: 60,
|
||||
timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id: 'activity-2',
|
||||
skillId: DEMO_SKILL_ID,
|
||||
xpEarned: 50,
|
||||
description: 'Unit Tests geschrieben',
|
||||
duration: 30,
|
||||
timestamp: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
},
|
||||
];
|
||||
71
apps/skilltree/apps/web/src/lib/data/local-store.ts
Normal file
71
apps/skilltree/apps/web/src/lib/data/local-store.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* SkilltTree — Local-First Data Layer (via @manacore/local-store)
|
||||
*
|
||||
* Adds unified sync support alongside the existing idb-based IndexedDB storage.
|
||||
* Skills, activities, and achievements are synced to the server when authenticated.
|
||||
*/
|
||||
|
||||
import { createLocalStore, type BaseRecord } from '@manacore/local-store';
|
||||
import { guestSkills, guestActivities } from './guest-seed';
|
||||
|
||||
// ─── Types ──────────────────────────────────────────────────
|
||||
|
||||
export interface LocalSkill extends BaseRecord {
|
||||
name: string;
|
||||
description: string;
|
||||
branch: 'intellect' | 'body' | 'creativity' | 'social' | 'practical' | 'mindset' | 'custom';
|
||||
parentId?: string | null;
|
||||
icon: string;
|
||||
color?: string | null;
|
||||
currentXp: number;
|
||||
totalXp: number;
|
||||
level: number;
|
||||
}
|
||||
|
||||
export interface LocalActivity extends BaseRecord {
|
||||
skillId: string;
|
||||
xpEarned: number;
|
||||
description: string;
|
||||
duration?: number | null;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
export interface LocalAchievement extends BaseRecord {
|
||||
key: string;
|
||||
name: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
unlockedAt: string;
|
||||
}
|
||||
|
||||
// ─── Store ──────────────────────────────────────────────────
|
||||
|
||||
const SYNC_SERVER_URL = import.meta.env.PUBLIC_SYNC_SERVER_URL || 'http://localhost:3050';
|
||||
|
||||
export const skilltreeStore = createLocalStore({
|
||||
appId: 'skilltree',
|
||||
collections: [
|
||||
{
|
||||
name: 'skills',
|
||||
indexes: ['branch', 'parentId', 'level'],
|
||||
guestSeed: guestSkills,
|
||||
},
|
||||
{
|
||||
name: 'activities',
|
||||
indexes: ['skillId', 'timestamp'],
|
||||
guestSeed: guestActivities,
|
||||
},
|
||||
{
|
||||
name: 'achievements',
|
||||
indexes: ['key', 'unlockedAt'],
|
||||
},
|
||||
],
|
||||
sync: {
|
||||
serverUrl: SYNC_SERVER_URL,
|
||||
},
|
||||
});
|
||||
|
||||
// Typed collection accessors
|
||||
export const skillCollection = skilltreeStore.collection<LocalSkill>('skills');
|
||||
export const activityCollection = skilltreeStore.collection<LocalActivity>('activities');
|
||||
export const achievementCollection = skilltreeStore.collection<LocalAchievement>('achievements');
|
||||
|
|
@ -8,10 +8,17 @@
|
|||
import { MiniOnboardingModal } from '@manacore/shared-app-onboarding';
|
||||
import { skilltreeOnboarding } from '$lib/stores/app-onboarding.svelte';
|
||||
import { SessionExpiredBanner, AuthGate } from '@manacore/shared-auth-ui';
|
||||
import { skilltreeStore } from '$lib/data/local-store';
|
||||
|
||||
let { children } = $props();
|
||||
|
||||
async function handleAuthReady() {
|
||||
// Initialize unified local-store (IndexedDB + sync)
|
||||
await skilltreeStore.initialize();
|
||||
if (authStore.isAuthenticated) {
|
||||
skilltreeStore.startSync(() => authStore.getValidToken());
|
||||
}
|
||||
// Initialize existing idb-based stores
|
||||
await skillStore.initialize();
|
||||
await achievementStore.initialize();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ ingress:
|
|||
- hostname: auth.mana.how
|
||||
service: http://localhost:3001
|
||||
|
||||
# API Gateway (Go)
|
||||
- hostname: api.mana.how
|
||||
service: http://localhost:3060
|
||||
|
||||
# Chat App
|
||||
- hostname: chat.mana.how
|
||||
service: http://localhost:5010
|
||||
|
|
@ -158,5 +162,17 @@ ingress:
|
|||
- hostname: docs.mana.how
|
||||
service: http://localhost:4400
|
||||
|
||||
# GPU Server (Windows PC, LAN: 192.168.178.11)
|
||||
- hostname: gpu-llm.mana.how
|
||||
service: http://192.168.178.11:3025
|
||||
- hostname: gpu-stt.mana.how
|
||||
service: http://192.168.178.11:3020
|
||||
- hostname: gpu-tts.mana.how
|
||||
service: http://192.168.178.11:3022
|
||||
- hostname: gpu-img.mana.how
|
||||
service: http://192.168.178.11:3023
|
||||
- hostname: gpu-ollama.mana.how
|
||||
service: http://192.168.178.11:11434
|
||||
|
||||
# Catch-all
|
||||
- service: http_status:404
|
||||
|
|
|
|||
|
|
@ -186,6 +186,64 @@ scrape_configs:
|
|||
metrics_path: '/_synapse/metrics'
|
||||
scrape_interval: 30s
|
||||
|
||||
# ============================================
|
||||
# GPU Server (Windows PC, LAN: 192.168.178.11)
|
||||
# ============================================
|
||||
|
||||
# GPU: LLM Gateway
|
||||
- job_name: 'gpu-llm'
|
||||
static_configs:
|
||||
- targets: ['192.168.178.11:3025']
|
||||
labels:
|
||||
instance: 'gpu-server'
|
||||
metrics_path: '/metrics'
|
||||
scrape_interval: 15s
|
||||
|
||||
# GPU: Speech-to-Text (WhisperX)
|
||||
- job_name: 'gpu-stt'
|
||||
static_configs:
|
||||
- targets: ['192.168.178.11:3020']
|
||||
labels:
|
||||
instance: 'gpu-server'
|
||||
metrics_path: '/health'
|
||||
scrape_interval: 30s
|
||||
|
||||
# GPU: Text-to-Speech
|
||||
- job_name: 'gpu-tts'
|
||||
static_configs:
|
||||
- targets: ['192.168.178.11:3022']
|
||||
labels:
|
||||
instance: 'gpu-server'
|
||||
metrics_path: '/health'
|
||||
scrape_interval: 30s
|
||||
|
||||
# GPU: Image Generation (FLUX.2)
|
||||
- job_name: 'gpu-image-gen'
|
||||
static_configs:
|
||||
- targets: ['192.168.178.11:3023']
|
||||
labels:
|
||||
instance: 'gpu-server'
|
||||
metrics_path: '/health'
|
||||
scrape_interval: 30s
|
||||
|
||||
# ============================================
|
||||
# Go Infrastructure Services
|
||||
# ============================================
|
||||
|
||||
# API Gateway (Go)
|
||||
- job_name: 'mana-api-gateway'
|
||||
static_configs:
|
||||
- targets: ['mana-api-gateway:3060']
|
||||
metrics_path: '/metrics'
|
||||
scrape_interval: 15s
|
||||
|
||||
# Matrix Bot (Go) — consolidated 21 bots
|
||||
- job_name: 'mana-matrix-bot'
|
||||
static_configs:
|
||||
- targets: ['mana-matrix-bot:4000']
|
||||
metrics_path: '/metrics'
|
||||
scrape_interval: 30s
|
||||
|
||||
# ============================================
|
||||
# Pushgateway (deploy metrics, batch jobs)
|
||||
# ============================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue