Merge pull request #6446 from influxdata/update-grafana-docs
New tools: Grafana plugin update, InfluxDB 3 ODBC and PowerBI connectorspull/6451/head
|
|
@ -73,6 +73,20 @@ exclude = [
|
|||
"^https?://claude\\.ai",
|
||||
"^https?://.*\\.claude\\.ai",
|
||||
|
||||
# Microsoft Learn documentation (bot detection/rate limiting)
|
||||
"^https?://learn\\.microsoft\\.com",
|
||||
"^https?://.*\\.microsoft\\.com/.*",
|
||||
|
||||
# Dremio download URLs (403 errors for automated requests)
|
||||
"^https?://download\\.dremio\\.com",
|
||||
|
||||
# Scarf analytics tracking pixels (certificate/network errors)
|
||||
"^https?://static\\.scarf\\.sh",
|
||||
|
||||
# Grafana documentation (bot detection/rate limiting)
|
||||
"^https?://grafana\\.com",
|
||||
"^https?://.*\\.grafana\\.com",
|
||||
|
||||
# Production site URLs (when testing locally, these should be relative)
|
||||
# This excludes canonical URLs and other absolute production URLs
|
||||
# TODO: Remove after fixing canonical URL generation or link-checker domain replacement
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ Redoc
|
|||
SQLAlchemy
|
||||
SQLAlchemy
|
||||
Splunk
|
||||
System.Data.Odbc
|
||||
[Ss]uperset
|
||||
TBs?
|
||||
\bUI\b
|
||||
|
|
|
|||
|
|
@ -0,0 +1,545 @@
|
|||
# TypeScript & Hugo Development Agent
|
||||
|
||||
You are a specialized TypeScript and Hugo development expert for the InfluxData documentation site. Your expertise spans TypeScript migration strategies, Hugo's asset pipeline, component-based architectures, and static site optimization.
|
||||
|
||||
## Core Expertise
|
||||
|
||||
### TypeScript Development
|
||||
- **Migration Strategy**: Guide incremental TypeScript adoption in existing ES6 modules
|
||||
- **Type Systems**: Create robust type definitions for documentation components
|
||||
- **Configuration**: Set up optimal `tsconfig.json` for Hugo browser environments
|
||||
- **Integration**: Configure TypeScript compilation within Hugo's asset pipeline
|
||||
- **Compatibility**: Ensure backward compatibility during migration phases
|
||||
|
||||
### Hugo Static Site Generator
|
||||
- **Asset Pipeline**: Deep understanding of Hugo's extended asset processing
|
||||
- **Build Process**: Optimize TypeScript compilation for Hugo's build system
|
||||
- **Shortcodes**: Integrate TypeScript components with Hugo shortcodes
|
||||
- **Templates**: Handle Hugo template data in TypeScript components
|
||||
- **Performance**: Optimize for both development (`hugo server`) and production builds
|
||||
|
||||
### Component Architecture
|
||||
- **Registry Pattern**: Maintain and enhance the existing component registry system
|
||||
- **Data Attributes**: Preserve `data-component` initialization pattern
|
||||
- **Module System**: Work with ES6 modules and TypeScript module resolution
|
||||
- **Service Layer**: Type and enhance services for API interactions
|
||||
- **Utilities**: Create strongly-typed utility functions
|
||||
|
||||
## Primary Responsibilities
|
||||
|
||||
### 1. TypeScript Migration Setup
|
||||
|
||||
#### Initial Configuration
|
||||
```typescript
|
||||
// tsconfig.json configuration for Hugo
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "ES2020",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": "./assets/js",
|
||||
"paths": {
|
||||
"@components/*": ["components/*"],
|
||||
"@services/*": ["services/*"],
|
||||
"@utils/*": ["utils/*"]
|
||||
},
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"incremental": true,
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"outDir": "./assets/js/dist",
|
||||
"rootDir": "./assets/js"
|
||||
},
|
||||
"include": ["assets/js/**/*"],
|
||||
"exclude": ["node_modules", "public", "resources"]
|
||||
}
|
||||
```
|
||||
|
||||
#### Hugo Pipeline Integration
|
||||
```yaml
|
||||
# config/_default/config.yaml
|
||||
build:
|
||||
useResourceCacheWhen: fallback
|
||||
writeStats: true
|
||||
|
||||
params:
|
||||
assets:
|
||||
typescript:
|
||||
enabled: true
|
||||
sourceMap: true
|
||||
minify: production
|
||||
```
|
||||
|
||||
### 2. Component Migration Pattern
|
||||
|
||||
#### TypeScript Component Template
|
||||
```typescript
|
||||
// components/example-component/example-component.ts
|
||||
interface ExampleComponentConfig {
|
||||
apiEndpoint?: string;
|
||||
refreshInterval?: number;
|
||||
onUpdate?: (data: unknown) => void;
|
||||
}
|
||||
|
||||
interface ExampleComponentElements {
|
||||
root: HTMLElement;
|
||||
trigger?: HTMLButtonElement;
|
||||
content?: HTMLDivElement;
|
||||
}
|
||||
|
||||
export class ExampleComponent {
|
||||
private config: Required<ExampleComponentConfig>;
|
||||
private elements: ExampleComponentElements;
|
||||
private state: Map<string, unknown> = new Map();
|
||||
|
||||
constructor(element: HTMLElement, config: ExampleComponentConfig = {}) {
|
||||
this.elements = { root: element };
|
||||
this.config = this.mergeConfig(config);
|
||||
this.init();
|
||||
}
|
||||
|
||||
private mergeConfig(config: ExampleComponentConfig): Required<ExampleComponentConfig> {
|
||||
return {
|
||||
apiEndpoint: config.apiEndpoint ?? '/api/default',
|
||||
refreshInterval: config.refreshInterval ?? 5000,
|
||||
onUpdate: config.onUpdate ?? (() => {})
|
||||
};
|
||||
}
|
||||
|
||||
private init(): void {
|
||||
this.cacheElements();
|
||||
this.bindEvents();
|
||||
this.render();
|
||||
}
|
||||
|
||||
private cacheElements(): void {
|
||||
this.elements.trigger = this.elements.root.querySelector('[data-trigger]') ?? undefined;
|
||||
this.elements.content = this.elements.root.querySelector('[data-content]') ?? undefined;
|
||||
}
|
||||
|
||||
private bindEvents(): void {
|
||||
this.elements.trigger?.addEventListener('click', this.handleClick.bind(this));
|
||||
}
|
||||
|
||||
private handleClick(event: MouseEvent): void {
|
||||
event.preventDefault();
|
||||
this.updateContent();
|
||||
}
|
||||
|
||||
private async updateContent(): Promise<void> {
|
||||
// Implementation
|
||||
}
|
||||
|
||||
private render(): void {
|
||||
// Implementation
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.elements.trigger?.removeEventListener('click', this.handleClick.bind(this));
|
||||
this.state.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Register with component registry
|
||||
import { registerComponent } from '@utils/component-registry';
|
||||
registerComponent('example-component', ExampleComponent);
|
||||
```
|
||||
|
||||
#### Migration Strategy for Existing Components
|
||||
```typescript
|
||||
// Step 1: Add type definitions alongside existing JS
|
||||
// types/components.d.ts
|
||||
declare module '@components/url-select' {
|
||||
export class UrlSelect {
|
||||
constructor(element: HTMLElement);
|
||||
destroy(): void;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: Create wrapper with types
|
||||
// components/url-select/url-select.ts
|
||||
import { UrlSelect as UrlSelectJS } from './url-select.js';
|
||||
|
||||
export interface UrlSelectConfig {
|
||||
storageKey?: string;
|
||||
defaultUrl?: string;
|
||||
}
|
||||
|
||||
export class UrlSelect extends UrlSelectJS {
|
||||
constructor(element: HTMLElement, config?: UrlSelectConfig) {
|
||||
super(element, config);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Gradually migrate internals to TypeScript
|
||||
```
|
||||
|
||||
### 3. Hugo Asset Pipeline Configuration
|
||||
|
||||
#### TypeScript Processing with Hugo Pipes
|
||||
```javascript
|
||||
// assets/js/main.ts (entry point)
|
||||
import { ComponentRegistry } from './utils/component-registry';
|
||||
import './components/index'; // Auto-register all components
|
||||
|
||||
// Initialize on DOM ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', ComponentRegistry.initializeAll);
|
||||
} else {
|
||||
ComponentRegistry.initializeAll();
|
||||
}
|
||||
|
||||
// Hugo template integration
|
||||
{{ $opts := dict "targetPath" "js/main.js" "minify" (eq hugo.Environment "production") }}
|
||||
{{ $ts := resources.Get "js/main.ts" | js.Build $opts }}
|
||||
{{ if eq hugo.Environment "development" }}
|
||||
<script src="{{ $ts.RelPermalink }}" defer></script>
|
||||
{{ else }}
|
||||
{{ $ts = $ts | fingerprint }}
|
||||
<script src="{{ $ts.RelPermalink }}" integrity="{{ $ts.Data.Integrity }}" defer></script>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
#### Build Performance Optimization
|
||||
```typescript
|
||||
// utils/lazy-loader.ts
|
||||
export class LazyLoader {
|
||||
private static cache = new Map<string, Promise<any>>();
|
||||
|
||||
static async loadComponent(name: string): Promise<any> {
|
||||
if (!this.cache.has(name)) {
|
||||
this.cache.set(name,
|
||||
import(/* webpackChunkName: "[request]" */ `@components/${name}/${name}`)
|
||||
);
|
||||
}
|
||||
return this.cache.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
// Usage in component registry
|
||||
async function initializeComponent(element: HTMLElement): Promise<void> {
|
||||
const componentName = element.dataset.component;
|
||||
if (!componentName) return;
|
||||
|
||||
const module = await LazyLoader.loadComponent(componentName);
|
||||
const Component = module.default || module[componentName];
|
||||
new Component(element);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Type Definitions for Hugo Context
|
||||
|
||||
```typescript
|
||||
// types/hugo.d.ts
|
||||
interface HugoPage {
|
||||
title: string;
|
||||
description: string;
|
||||
permalink: string;
|
||||
section: string;
|
||||
params: Record<string, unknown>;
|
||||
}
|
||||
|
||||
interface HugoSite {
|
||||
baseURL: string;
|
||||
languageCode: string;
|
||||
params: {
|
||||
influxdb_urls: Array<{
|
||||
url: string;
|
||||
name: string;
|
||||
cloud?: boolean;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
Hugo: {
|
||||
page: HugoPage;
|
||||
site: HugoSite;
|
||||
};
|
||||
docsData: {
|
||||
page: HugoPage;
|
||||
site: HugoSite;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
```
|
||||
|
||||
### 5. Testing Integration
|
||||
|
||||
#### Cypress with TypeScript
|
||||
```typescript
|
||||
// cypress/support/commands.ts
|
||||
Cypress.Commands.add('initComponent', (componentName: string, config?: Record<string, unknown>) => {
|
||||
cy.window().then((win) => {
|
||||
const element = win.document.querySelector(`[data-component="${componentName}"]`);
|
||||
if (element) {
|
||||
// Initialize component with TypeScript
|
||||
const event = new CustomEvent('component:init', { detail: config });
|
||||
element.dispatchEvent(event);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// cypress/support/index.d.ts
|
||||
declare namespace Cypress {
|
||||
interface Chainable {
|
||||
initComponent(componentName: string, config?: Record<string, unknown>): Chainable<void>;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Development Workflow
|
||||
|
||||
#### NPM Scripts for TypeScript Development
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"ts:check": "tsc --noEmit",
|
||||
"ts:build": "tsc",
|
||||
"ts:watch": "tsc --watch",
|
||||
"dev": "concurrently \"yarn ts:watch\" \"hugo server\"",
|
||||
"build": "yarn ts:build && hugo --minify",
|
||||
"lint:ts": "eslint 'assets/js/**/*.ts'",
|
||||
"format:ts": "prettier --write 'assets/js/**/*.ts'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### VSCode Configuration
|
||||
```json
|
||||
// .vscode/settings.json
|
||||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
}
|
||||
},
|
||||
"typescript.preferences.importModuleSpecifier": "relative",
|
||||
"typescript.preferences.quoteStyle": "single"
|
||||
}
|
||||
```
|
||||
|
||||
## Migration Guidelines
|
||||
|
||||
### Phase 1: Setup (Week 1)
|
||||
1. Install TypeScript and type definitions
|
||||
2. Configure `tsconfig.json` for Hugo environment
|
||||
3. Set up build scripts and Hugo pipeline
|
||||
4. Create type definitions for existing globals
|
||||
|
||||
### Phase 2: Type Definitions (Week 2)
|
||||
1. Create `.d.ts` files for existing JS modules
|
||||
2. Add type definitions for Hugo context
|
||||
3. Type external dependencies
|
||||
4. Set up ambient declarations
|
||||
|
||||
### Phase 3: Incremental Migration (Weeks 3-8)
|
||||
1. Start with utility modules (pure functions)
|
||||
2. Migrate service layer (API interactions)
|
||||
3. Convert leaf components (no dependencies)
|
||||
4. Migrate complex components
|
||||
5. Update component registry
|
||||
|
||||
### Phase 4: Optimization (Week 9-10)
|
||||
1. Implement code splitting
|
||||
2. Set up lazy loading
|
||||
3. Optimize build performance
|
||||
4. Configure production builds
|
||||
|
||||
## Best Practices
|
||||
|
||||
### TypeScript Conventions
|
||||
- Use strict mode from the start
|
||||
- Prefer interfaces over type aliases for objects
|
||||
- Use const assertions for literal types
|
||||
- Implement proper error boundaries
|
||||
- Use discriminated unions for state management
|
||||
|
||||
### Hugo Integration
|
||||
- Leverage Hugo's build stats for optimization
|
||||
- Use resource bundling for related assets
|
||||
- Implement proper cache busting
|
||||
- Utilize Hugo's minification in production
|
||||
- Keep source maps in development only
|
||||
|
||||
### Component Guidelines
|
||||
- One component per file
|
||||
- Co-locate types with implementation
|
||||
- Use composition over inheritance
|
||||
- Implement cleanup in destroy methods
|
||||
- Follow single responsibility principle
|
||||
|
||||
### Performance Considerations
|
||||
- Use dynamic imports for large components
|
||||
- Implement intersection observer for lazy loading
|
||||
- Minimize bundle size with tree shaking
|
||||
- Use TypeScript's `const enum` for better optimization
|
||||
- Leverage browser caching strategies
|
||||
|
||||
## Debugging Strategies
|
||||
|
||||
### Development Tools
|
||||
```typescript
|
||||
// utils/debug.ts
|
||||
export const debug = {
|
||||
log: (component: string, message: string, data?: unknown): void => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log(`[${component}]`, message, data);
|
||||
}
|
||||
},
|
||||
|
||||
time: (label: string): void => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.time(label);
|
||||
}
|
||||
},
|
||||
|
||||
timeEnd: (label: string): void => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.timeEnd(label);
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Source Maps Configuration
|
||||
```javascript
|
||||
// hugo.config.js for development
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.ts$/,
|
||||
use: {
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
compilerOptions: {
|
||||
sourceMap: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
devtool: 'inline-source-map'
|
||||
};
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### State Management
|
||||
```typescript
|
||||
// utils/state-manager.ts
|
||||
export class StateManager<T extends Record<string, unknown>> {
|
||||
private state: T;
|
||||
private listeners: Set<(state: T) => void> = new Set();
|
||||
|
||||
constructor(initialState: T) {
|
||||
this.state = { ...initialState };
|
||||
}
|
||||
|
||||
get current(): Readonly<T> {
|
||||
return Object.freeze({ ...this.state });
|
||||
}
|
||||
|
||||
update(updates: Partial<T>): void {
|
||||
this.state = { ...this.state, ...updates };
|
||||
this.notify();
|
||||
}
|
||||
|
||||
subscribe(listener: (state: T) => void): () => void {
|
||||
this.listeners.add(listener);
|
||||
return () => this.listeners.delete(listener);
|
||||
}
|
||||
|
||||
private notify(): void {
|
||||
this.listeners.forEach(listener => listener(this.current));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### API Service Pattern
|
||||
```typescript
|
||||
// services/base-service.ts
|
||||
export abstract class BaseService {
|
||||
protected baseURL: string;
|
||||
protected headers: HeadersInit;
|
||||
|
||||
constructor(baseURL: string = '') {
|
||||
this.baseURL = baseURL;
|
||||
this.headers = {
|
||||
'Content-Type': 'application/json'
|
||||
};
|
||||
}
|
||||
|
||||
protected async request<T>(
|
||||
endpoint: string,
|
||||
options: RequestInit = {}
|
||||
): Promise<T> {
|
||||
const url = `${this.baseURL}${endpoint}`;
|
||||
const config: RequestInit = {
|
||||
...options,
|
||||
headers: { ...this.headers, ...options.headers }
|
||||
};
|
||||
|
||||
const response = await fetch(url, config);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting Guide
|
||||
|
||||
### Common Issues and Solutions
|
||||
|
||||
1. **Module Resolution Issues**
|
||||
- Check `tsconfig.json` paths configuration
|
||||
- Verify Hugo's asset directory structure
|
||||
- Ensure proper file extensions in imports
|
||||
|
||||
2. **Type Definition Conflicts**
|
||||
- Use namespace isolation for global types
|
||||
- Check for duplicate declarations
|
||||
- Verify ambient module declarations
|
||||
|
||||
3. **Build Performance**
|
||||
- Enable incremental compilation
|
||||
- Use project references for large codebases
|
||||
- Implement proper code splitting
|
||||
|
||||
4. **Runtime Errors**
|
||||
- Verify TypeScript target matches browser support
|
||||
- Check for proper polyfills
|
||||
- Ensure correct module format for Hugo
|
||||
|
||||
5. **Hugo Integration Issues**
|
||||
- Verify resource pipeline configuration
|
||||
- Check for proper asset fingerprinting
|
||||
- Ensure correct build environment detection
|
||||
|
||||
## Reference Documentation
|
||||
|
||||
- [TypeScript Documentation](https://www.typescriptlang.org/docs/)
|
||||
- [Hugo Pipes Documentation](https://gohugo.io/hugo-pipes/)
|
||||
- [ESBuild with Hugo](https://gohugo.io/hugo-pipes/js/)
|
||||
- [TypeScript ESLint](https://typescript-eslint.io/)
|
||||
- [Cypress TypeScript](https://docs.cypress.io/guides/tooling/typescript-support)
|
||||
|
|
@ -201,6 +201,7 @@ those frontmatter keys. Frontmatter defined on the page overrides frontmatter
|
|||
|
||||
#### Use shared content in a page
|
||||
|
||||
This repository makes heavy use of shared content to avoid duplication across InfluxDB editions and versions.
|
||||
Use the `source` frontmatter to specify a shared file to use to populate the
|
||||
page content. Shared files are typically stored in the `/content/shared` directory.
|
||||
|
||||
|
|
@ -225,6 +226,9 @@ The keyword `version` gets replaced during the build process with the appropriat
|
|||
[CLI serve command](/influxdb3/{{% product-key %}}/reference/cli/influxdb3/serve/)
|
||||
```
|
||||
|
||||
Don't list links to related content at the bottom of shared content files.
|
||||
Instead, add the `related` frontmatter to the individual pages that use the shared content.
|
||||
|
||||
#### Shortcodes in Markdown files
|
||||
|
||||
For the complete shortcodes reference, see `/.github/instructions/shortcodes-reference.instructions.md`.
|
||||
|
|
|
|||
|
|
@ -176,4 +176,3 @@ docker compose run -T vale --config=content/influxdb/cloud-dedicated/.vale.ini -
|
|||
#### Configure style rules
|
||||
|
||||
_See full CONTRIBUTING.md for complete details._
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ tmp
|
|||
.idea
|
||||
**/config.toml
|
||||
|
||||
# TypeScript build output
|
||||
**/dist/
|
||||
|
||||
# User context files for AI assistant tools
|
||||
.context/*
|
||||
!.context/README.md
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ LEFTHOOK=0 git commit
|
|||
yarn test:e2e
|
||||
|
||||
# Run specific E2E specs
|
||||
node cypress/support/run-e2e-specs.js --spec "cypress/e2e/content/article-links.cy.js"
|
||||
node cypress/support/run-e2e-specs.js --spec "cypress/e2e/content/index.cy.js"
|
||||
```
|
||||
|
||||
### JavaScript Testing and Debugging
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import DocSearch from './components/doc-search.js';
|
|||
import FeatureCallout from './feature-callouts.js';
|
||||
import FluxGroupKeysDemo from './flux-group-keys.js';
|
||||
import FluxInfluxDBVersionsTrigger from './flux-influxdb-versions.js';
|
||||
import InfluxDBVersionDetector from './influxdb-version-detector.ts';
|
||||
import KeyBinding from './keybindings.js';
|
||||
import ListFilters from './list-filters.js';
|
||||
import ProductSelector from './version-selector.js';
|
||||
|
|
@ -64,6 +65,7 @@ const componentRegistry = {
|
|||
'feature-callout': FeatureCallout,
|
||||
'flux-group-keys-demo': FluxGroupKeysDemo,
|
||||
'flux-influxdb-versions-trigger': FluxInfluxDBVersionsTrigger,
|
||||
'influxdb-version-detector': InfluxDBVersionDetector,
|
||||
keybinding: KeyBinding,
|
||||
'list-filters': ListFilters,
|
||||
'product-selector': ProductSelector,
|
||||
|
|
@ -113,7 +115,10 @@ function initComponents(globals) {
|
|||
if (ComponentConstructor) {
|
||||
// Initialize the component and store its instance in the global namespace
|
||||
try {
|
||||
const instance = ComponentConstructor({ component });
|
||||
// Prepare component options
|
||||
const options = { component };
|
||||
|
||||
const instance = ComponentConstructor(options);
|
||||
globals[componentName] = ComponentConstructor;
|
||||
|
||||
// Optionally store component instances for future reference
|
||||
|
|
|
|||
|
|
@ -0,0 +1,647 @@
|
|||
// InfluxDB Version Detector Component Styles
|
||||
|
||||
.influxdb-version-detector {
|
||||
// CSS Custom Properties
|
||||
--transition-fast: 0.2s ease;
|
||||
--transition-normal: 0.3s ease;
|
||||
--spacing-sm: 0.625rem;
|
||||
--spacing-md: 1.25rem;
|
||||
|
||||
margin: 2rem auto;
|
||||
|
||||
.detector-title {
|
||||
color: $article-heading;
|
||||
margin-bottom: 0.625rem;
|
||||
font-size: 1.8em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.detector-subtitle {
|
||||
color: $article-text;
|
||||
margin-bottom: 1.875rem;
|
||||
font-size: 0.95em;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
// Progress bar
|
||||
.progress {
|
||||
margin-bottom: 1.5625rem;
|
||||
height: 6px;
|
||||
background: $article-hr;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
background: $article-link;
|
||||
transition: width var(--transition-normal);
|
||||
}
|
||||
}
|
||||
|
||||
// Question container
|
||||
.question-container {
|
||||
min-height: 150px;
|
||||
|
||||
.question {
|
||||
display: none;
|
||||
animation: fadeIn var(--transition-normal);
|
||||
|
||||
&.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.question-text {
|
||||
font-size: 1.1em;
|
||||
color: $article-heading;
|
||||
margin-bottom: 1.25rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Buttons - Base styles and variants
|
||||
%button-base {
|
||||
border: none;
|
||||
border-radius: var(--border-radius);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
font-family: inherit;
|
||||
|
||||
&:focus {
|
||||
outline: 2px solid $article-link;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.option-button {
|
||||
@extend %button-base;
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
margin-bottom: 0.75rem;
|
||||
padding: 0.875rem 1.125rem;
|
||||
background: $article-bg;
|
||||
color: $article-text;
|
||||
border: 2px solid $article-hr;
|
||||
font-size: 15px;
|
||||
|
||||
&:hover {
|
||||
border-color: $article-link;
|
||||
background: $article-bg;
|
||||
transform: translateX(3px);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateX(1px);
|
||||
}
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
@extend %button-base;
|
||||
background: $article-link;
|
||||
color: $g20-white;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
background: $b-ocean;
|
||||
color: $g20-white;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: $g8-storm;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.back-button {
|
||||
@extend %button-base;
|
||||
background: $g8-storm;
|
||||
color: $g20-white;
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
font-size: 14px;
|
||||
margin-right: var(--spacing-sm);
|
||||
|
||||
&:hover {
|
||||
background: $g9-mountain;
|
||||
}
|
||||
}
|
||||
|
||||
.restart-button {
|
||||
@extend .back-button;
|
||||
margin-top: var(--spacing-md);
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
// Input fields
|
||||
%input-base {
|
||||
width: 100%;
|
||||
border: 2px solid $article-hr;
|
||||
border-radius: var(--border-radius);
|
||||
transition: border-color var(--transition-fast);
|
||||
background: $article-bg;
|
||||
color: $article-text;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: $article-link;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group {
|
||||
margin-bottom: var(--spacing-md);
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
color: $article-text;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
input {
|
||||
@extend %input-base;
|
||||
padding: 0.75rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
@extend %input-base;
|
||||
padding: var(--spacing-sm);
|
||||
font-family: var(--font-mono, 'Courier New', monospace);
|
||||
font-size: 12px;
|
||||
resize: vertical;
|
||||
min-height: 120px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba($article-text, 0.6);
|
||||
opacity: 1; // Firefox fix
|
||||
}
|
||||
|
||||
&::-webkit-input-placeholder {
|
||||
color: rgba($article-text, 0.6);
|
||||
}
|
||||
|
||||
&::-moz-placeholder {
|
||||
color: rgba($article-text, 0.6);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:-ms-input-placeholder {
|
||||
color: rgba($article-text, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
// Code block - match site standards
|
||||
.code-block {
|
||||
background: $article-code-bg;
|
||||
color: $article-code;
|
||||
padding: 1.75rem 1.75rem 1.25rem;
|
||||
border-radius: $radius;
|
||||
font-family: $code;
|
||||
font-size: 1rem;
|
||||
margin: 2rem 0 2.25rem;
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
line-height: 1.7rem;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
// URL pattern hint
|
||||
.url-pattern-hint {
|
||||
margin-bottom: var(--spacing-sm);
|
||||
padding: var(--spacing-sm);
|
||||
background: $article-note-base;
|
||||
border: 1px solid $article-note-base;
|
||||
border-radius: var(--border-radius);
|
||||
color: $article-note-text;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
// URL suggestions
|
||||
.url-suggestions {
|
||||
margin-bottom: var(--spacing-md);
|
||||
|
||||
.suggestions-header {
|
||||
color: $article-heading;
|
||||
margin-bottom: var(--spacing-sm);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.suggestion-button {
|
||||
@extend %button-base;
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
margin-bottom: var(--spacing-sm);
|
||||
padding: var(--spacing-sm);
|
||||
background: $article-bg;
|
||||
border: 1px solid $article-hr;
|
||||
|
||||
&:hover {
|
||||
border-color: $article-link;
|
||||
background: $article-bg;
|
||||
}
|
||||
|
||||
.suggestion-url {
|
||||
font-family: var(--font-mono, 'Courier New', monospace);
|
||||
font-size: 13px;
|
||||
color: $article-link;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.suggestion-product {
|
||||
font-size: 12px;
|
||||
color: $article-text;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.suggestion-pattern {
|
||||
font-size: 11px;
|
||||
color: $article-link;
|
||||
font-style: italic;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Results
|
||||
.result {
|
||||
display: none;
|
||||
margin-top: var(--spacing-sm);
|
||||
padding: var(--spacing-md);
|
||||
border-radius: var(--border-radius);
|
||||
animation: fadeIn var(--transition-normal);
|
||||
|
||||
&.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.success {
|
||||
background: $article-bg;
|
||||
border-left: 3px solid $article-note-base;
|
||||
color: $article-text;
|
||||
}
|
||||
|
||||
&.error {
|
||||
background: $r-flan;
|
||||
border-left: 3px solid $article-caution-base;
|
||||
color: $r-basalt;
|
||||
}
|
||||
|
||||
&.info {
|
||||
background: $article-note-base;
|
||||
border-left: 3px solid $article-note-base;
|
||||
color: $article-note-text;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background: $article-warning-bg;
|
||||
border-left: 3px solid $article-warning-base;
|
||||
color: $article-warning-text;
|
||||
}
|
||||
}
|
||||
|
||||
.detected-version {
|
||||
font-size: 1.3em;
|
||||
font-weight: bold;
|
||||
color: $article-link;
|
||||
margin-bottom: var(--spacing-sm);
|
||||
padding: var(--spacing-sm);
|
||||
background: rgba($article-link, 0.1);
|
||||
border-radius: 4px;
|
||||
border-left: 4px solid $article-link;
|
||||
}
|
||||
|
||||
// URL pre-filled indicator
|
||||
.url-prefilled-indicator {
|
||||
font-size: 0.85em;
|
||||
color: $article-note-text;
|
||||
margin-bottom: 8px;
|
||||
padding: 4px 8px;
|
||||
background: rgba($article-link, 0.1);
|
||||
border-left: 3px solid $article-link;
|
||||
}
|
||||
|
||||
// Loading animation
|
||||
.loading {
|
||||
display: inline-block;
|
||||
margin-left: var(--spacing-sm);
|
||||
|
||||
&:after {
|
||||
content: '...';
|
||||
animation: dots 1.5s steps(4, end) infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dots {
|
||||
0%, 20% {
|
||||
content: '.';
|
||||
}
|
||||
40% {
|
||||
content: '..';
|
||||
}
|
||||
60%, 100% {
|
||||
content: '...';
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Responsive design
|
||||
@media (max-width: 768px) {
|
||||
padding: 1.5rem;
|
||||
|
||||
.detector-title {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.option-button {
|
||||
padding: 0.75rem 1rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.submit-button,
|
||||
.back-button {
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
padding: 1rem;
|
||||
|
||||
.detector-title {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.detector-subtitle {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.question-text {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Product ranking results
|
||||
.product-ranking {
|
||||
margin-bottom: var(--spacing-sm);
|
||||
padding: 0.75rem;
|
||||
border-radius: var(--border-radius);
|
||||
border-left: 4px solid $article-hr;
|
||||
background: $article-bg;
|
||||
|
||||
&.top-result {
|
||||
background: rgba($article-link, 0.1);
|
||||
border-color: $article-link;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.most-likely-label {
|
||||
color: $article-link;
|
||||
font-size: 0.9em;
|
||||
margin-left: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.product-details {
|
||||
color: $article-text;
|
||||
font-size: 0.9em;
|
||||
margin-top: 0.25rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
// Grafana networking tips
|
||||
.grafana-tips {
|
||||
margin-top: var(--spacing-md);
|
||||
padding: 1rem;
|
||||
background: rgba($article-link, 0.1);
|
||||
border-left: 4px solid $article-link;
|
||||
border-radius: var(--border-radius);
|
||||
|
||||
.tips-title {
|
||||
margin: 0 0 var(--spacing-sm) 0;
|
||||
color: $article-link;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.tips-description {
|
||||
margin: 0 0 var(--spacing-sm) 0;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.tips-list {
|
||||
margin: 0;
|
||||
padding-left: 1.25rem;
|
||||
font-size: 0.85em;
|
||||
|
||||
li {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
code {
|
||||
background: rgba($article-link, 0.15);
|
||||
padding: 0.125rem 0.25rem;
|
||||
border-radius: 3px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}
|
||||
|
||||
.tips-link {
|
||||
margin: var(--spacing-sm) 0 0 0;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
}
|
||||
|
||||
// Expected results section
|
||||
.expected-results {
|
||||
margin: 1rem 0;
|
||||
|
||||
.results-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.results-list {
|
||||
margin: 0;
|
||||
padding-left: 1rem;
|
||||
font-size: 0.9em;
|
||||
|
||||
li {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Question text styling
|
||||
.question-text-spaced {
|
||||
margin-top: 1rem;
|
||||
font-weight: normal;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
.question-options {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
// Command help section
|
||||
.command-help {
|
||||
margin-top: var(--spacing-md);
|
||||
}
|
||||
|
||||
// Grafana links styling
|
||||
.grafana-link {
|
||||
color: $article-link;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
color: $article-link-hover;
|
||||
}
|
||||
}
|
||||
|
||||
// Manual command output
|
||||
.manual-output {
|
||||
margin: 1rem 0;
|
||||
padding: var(--spacing-sm);
|
||||
background: $article-bg;
|
||||
border-left: 4px solid $article-link;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
// Action section with buttons
|
||||
.action-section {
|
||||
margin-top: var(--spacing-md);
|
||||
}
|
||||
|
||||
// Quick Reference expandable section
|
||||
.quick-reference {
|
||||
margin-top: 2rem;
|
||||
|
||||
details {
|
||||
border: 1px solid $article-hr;
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.reference-summary {
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
padding: 0.5rem 0;
|
||||
user-select: none;
|
||||
color: $article-link;
|
||||
|
||||
&:hover {
|
||||
color: $article-link-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expandable summary styling (for Docker Commands, etc.)
|
||||
.expandable-summary {
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
padding: 0.5rem 0;
|
||||
user-select: none;
|
||||
color: $article-link;
|
||||
position: relative;
|
||||
padding-left: 1.5rem; // Make room for custom icon
|
||||
|
||||
&:hover {
|
||||
color: $article-link-hover;
|
||||
}
|
||||
|
||||
// Hide the default disclosure triangle
|
||||
&::marker,
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Add custom plus/minus icon
|
||||
&::before {
|
||||
content: '+';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: $article-link;
|
||||
border: 1px solid $article-link;
|
||||
border-radius: 3px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
// Change to minus when expanded
|
||||
details[open] & {
|
||||
&::before {
|
||||
content: '−';
|
||||
}
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
color: $article-link-hover;
|
||||
border-color: $article-link-hover;
|
||||
}
|
||||
}
|
||||
|
||||
// Quick Reference expandable section
|
||||
.quick-reference {
|
||||
margin-top: 2rem;
|
||||
|
||||
details {
|
||||
border: 1px solid $article-hr;
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.reference-table {
|
||||
margin-top: 1rem;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.9em;
|
||||
|
||||
th, td {
|
||||
padding: 0.5rem;
|
||||
text-align: left;
|
||||
border: 1px solid $article-hr;
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 0.75rem 0.5rem;
|
||||
background: rgba($article-link, 0.1);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) {
|
||||
background: rgba($article-text, 0.02);
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -26,7 +26,8 @@
|
|||
.modal-body {
|
||||
position: relative;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
// width: 100%;
|
||||
max-width: 650px;
|
||||
max-height: 97.5vh;
|
||||
|
|
@ -37,6 +38,27 @@
|
|||
color: $article-text;
|
||||
font-size: 1rem;
|
||||
transition: margin .4s;
|
||||
scroll-behavior: smooth;
|
||||
-webkit-overflow-scrolling: touch; // iOS smooth scrolling
|
||||
|
||||
// Custom scrollbar styling
|
||||
&::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: rgba($article-hr, 0.2);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba($article-text, 0.3);
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: rgba($article-text, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.open {
|
||||
|
|
@ -62,6 +84,7 @@
|
|||
overflow: visible;
|
||||
width: 586px;
|
||||
max-width: 100%;
|
||||
flex-shrink: 0;
|
||||
|
||||
h3 {
|
||||
color: $article-heading;
|
||||
|
|
|
|||
|
|
@ -34,3 +34,6 @@
|
|||
"layouts/code-controls",
|
||||
"layouts/v3-wayfinding";
|
||||
|
||||
// Import Components
|
||||
@import "components/influxdb-version-detector";
|
||||
|
||||
|
|
|
|||
|
|
@ -8,128 +8,134 @@ menu:
|
|||
name: Grafana
|
||||
weight: 60
|
||||
parent: Tools
|
||||
related:
|
||||
- /flux/v0/get-started/, Get started with Flux
|
||||
- https://grafana.com/docs/, Grafana documentation
|
||||
alt_links:
|
||||
core: /influxdb3/core/visualize-data/grafana/
|
||||
enterprise: /influxdb3/enterprise/visualize-data/grafana/
|
||||
cloud-serverless: /influxdb3/cloud-serverless/process-data/visualize/grafana/
|
||||
cloud-dedicated: /influxdb3/cloud-dedicated/process-data/visualize/grafana/
|
||||
clustered: /influxdb3/clustered/process-data/visualize/grafana/
|
||||
canonical: /influxdb/v2/tools/grafana/
|
||||
---
|
||||
|
||||
Use [Grafana](https://grafana.com/) or [Grafana Cloud](https://grafana.com/products/cloud/)
|
||||
to visualize data from your **InfluxDB Enterprise** cluster.
|
||||
|
||||
{{% note %}}
|
||||
#### Required
|
||||
- The instructions in this guide require **Grafana Cloud** or **Grafana v10.3+**.
|
||||
For information about using InfluxDB with other versions of Grafana,
|
||||
see the [Grafana documentation](https://grafana.com/docs/grafana/latest/datasources/influxdb/).
|
||||
- To use **Flux**, use **InfluxDB 1.8.1+** and [enable Flux](/influxdb/v1/flux/installation/)
|
||||
in your InfluxDB configuration file.
|
||||
{{% /note %}}
|
||||
> [!Note]
|
||||
> {{< influxdb-version-detector >}}
|
||||
|
||||
1. [Set up an InfluxDB Enterprise cluster](/enterprise_influxdb/v1/introduction/installation/).
|
||||
2. [Sign up for Grafana Cloud](https://grafana.com/products/cloud/) or
|
||||
[download and install Grafana](https://grafana.com/grafana/download).
|
||||
3. Visit your **Grafana Cloud user interface** (UI) or, if running Grafana locally,
|
||||
[start Grafana](https://grafana.com/docs/grafana/latest/installation/) and visit
|
||||
<http://localhost:3000> in your browser.
|
||||
4. In the left navigation of the Grafana UI, expand the **Connections** section
|
||||
and click **Add new connection**.
|
||||
5. Select **InfluxDB** from the list of available data sources and click
|
||||
**Add data source**.
|
||||
6. On the **Data Source configuration page**, enter a **name** for your InfluxDB data source.
|
||||
7. In the **Query Language** drop-down menu, select one of the query languages
|
||||
supported by InfluxDB {{< current-version >}} (InfluxQL or Flux):
|
||||
> [!Note]
|
||||
> #### Required
|
||||
> - The instructions in this guide require **Grafana Cloud** or **Grafana v10.3+**.
|
||||
> For information about using InfluxDB with other versions of Grafana,
|
||||
> see the [Grafana documentation](https://grafana.com/docs/grafana/latest/datasources/influxdb/).
|
||||
> - To use **Flux**, use **InfluxDB 1.8.1+** and [enable Flux](/enterprise_influxdb/v1/flux/installation/)
|
||||
> in your InfluxDB data nodes.
|
||||
|
||||
{{% note %}}
|
||||
SQL is only supported in InfluxDB 3.
|
||||
{{% /note %}}
|
||||
- [Install Grafana](#install-grafana)
|
||||
- [Create an InfluxDB data source](#create-an-influxdb-data-source)
|
||||
- [Query and visualize data](#query-and-visualize-data)
|
||||
|
||||
## Install Grafana
|
||||
|
||||
1. [Set up an InfluxDB Enterprise cluster](/enterprise_influxdb/v1/introduction/installation/).
|
||||
2. [Sign up for Grafana Cloud](https://grafana.com/products/cloud/) or
|
||||
[download and install Grafana](https://grafana.com/grafana/download).
|
||||
3. Visit your **Grafana Cloud user interface** (UI) or, if running Grafana locally,
|
||||
[start Grafana](https://grafana.com/docs/grafana/latest/installation/) and visit
|
||||
<http://localhost:3000> in your browser.
|
||||
|
||||
> [!Note]
|
||||
> #### Using Grafana Cloud with a local InfluxDB instance
|
||||
>
|
||||
> If you need to keep your database local, consider running Grafana locally instead of using Grafana Cloud,
|
||||
> as this avoids the need to expose your database to the internet.
|
||||
>
|
||||
> To use InfluxDB running on your private network with Grafana Cloud, you must
|
||||
> [configure a private data source](https://grafana.com/docs/grafana-cloud/data-sources/private-data-sources/).
|
||||
> See the Grafana documentation for instructions on configuring a Grafana Cloud private data source
|
||||
> with {{% product-name %}} running on `http://localhost:8086`.
|
||||
|
||||
> [!Note]
|
||||
> #### Query language support
|
||||
> - InfluxQL is supported in InfluxDB Enterprise v1.8.x and later.
|
||||
> - Flux is supported in InfluxDB Enterprise v1.8.1 and later.
|
||||
> - SQL is only supported in InfluxDB 3. For more information, see how to [get started with InfluxDB 3 Enterprise](/influxdb3/enterprise/get-started/).
|
||||
|
||||
## Create an InfluxDB data source
|
||||
|
||||
1. In your Grafana interface, click **Connections** in the left sidebar
|
||||
2. Click **Data sources**
|
||||
3. Click **Add new connection**
|
||||
4. Search for and select **InfluxDB**. The InfluxDB data source configuration page displays.
|
||||
5. In the **Settings** tab, configure the following:
|
||||
|
||||
- **Name**: A descriptive name for your data source
|
||||
- **URL**: Your server or load balancer URL--for example, `https://{{< influxdb/host >}}`
|
||||
- **Product**: From the dropdown, select **InfluxDB Enterprise 1.x**
|
||||
- **Query Language**: Select **InfluxQL** or **Flux**
|
||||
|
||||
### Configure database settings
|
||||
|
||||
The fields in this section change based on your query language selection.
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
[InfluxQL](#)
|
||||
[Flux](#)
|
||||
{{% /tabs %}}
|
||||
<!--------------------------- BEGIN INFLUXQL CONTENT -------------------------->
|
||||
{{% tab-content %}}
|
||||
<!--------------------------- BEGIN INFLUXQL CONTENT -------------------------->
|
||||
|
||||
## Configure Grafana to use InfluxQL
|
||||
|
||||
With **InfluxQL** selected as the query language in your InfluxDB data source settings:
|
||||
When you select **InfluxQL** as the query language, configure the following:
|
||||
|
||||
1. Under **HTTP**, enter the following:
|
||||
- **Database**: Your database name
|
||||
- **User**: Your InfluxDB username _(if [authentication is enabled](/enterprise_influxdb/v1/administration/authentication_and_authorization/))_
|
||||
- **Password**: Your InfluxDB password _(if [authentication is enabled](/enterprise_influxdb/v1/administration/authentication_and_authorization/))_
|
||||
|
||||
- **URL**: Your **InfluxDB Enterprise URL** or **load balancer URL**.
|
||||
{{< img-hd src="/img/influxdb3/enterprise-v1-grafana-product-dropdown-flux.png" alt="InfluxQL configuration for InfluxDB Enterprise 1.x" />}}
|
||||
|
||||
```sh
|
||||
http://localhost:8086
|
||||
```
|
||||
Click **Save & Test**. Grafana attempts to connect to InfluxDB Enterprise and returns the result of the test.
|
||||
|
||||
2. Under **InfluxDB Details**, enter the following:
|
||||
|
||||
- **Database**: your database name
|
||||
- **User**: your InfluxDB username _(if [authentication is enabled](/enterprise_influxdb/v1/administration/authentication_and_authorization/))_
|
||||
- **Password**: your InfluxDB password _(if [authentication is enabled](/enterprise_influxdb/v1/administration/authentication_and_authorization/))_
|
||||
- **HTTP Method**: Select **GET** or **POST** _(for differences between the two,
|
||||
see the [query HTTP endpoint documentation](/enterprise_influxdb/v1/tools/api/#query-http-endpoint))_
|
||||
|
||||
3. Provide a **[Min time interval](https://grafana.com/docs/grafana/latest/datasources/influxdb/#min-time-interval)**
|
||||
(default is 10s).
|
||||
|
||||
{{< img-hd src="/img/influxdb/v1-tools-grafana-influxql.png" />}}
|
||||
|
||||
4. Click **Save & Test**. Grafana attempts to connect to InfluxDB and returns
|
||||
the result of the test.
|
||||
|
||||
{{% /tab-content %}}
|
||||
<!---------------------------- END INFLUXQL CONTENT --------------------------->
|
||||
<!----------------------------- BEGIN FLUX CONTENT ---------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{% tab-content %}}
|
||||
<!----------------------------- BEGIN FLUX CONTENT ---------------------------->
|
||||
|
||||
## Configure Grafana to use Flux
|
||||
|
||||
With **Flux** selected as the query language in your InfluxDB data source,
|
||||
configure your InfluxDB connection:
|
||||
When you select **Flux** as the query language, configure the following:
|
||||
|
||||
1. Ensure [Flux is enabled](/enterprise_influxdb/v1/flux/installation/) in
|
||||
your InfluxDB Enterprise data nodes.
|
||||
1. Ensure [Flux is enabled](/enterprise_influxdb/v1/flux/installation/) in your InfluxDB Enterprise data nodes.
|
||||
|
||||
2. Under **HTTP**, enter the following:
|
||||
2. Configure the database settings:
|
||||
|
||||
- **URL**: Your **InfluxDB Enterprise URL** or **load balancer URL**.
|
||||
- **Organization**: Provide an arbitrary value (InfluxDB Enterprise 1.x does not use organizations)
|
||||
- **Default Bucket**: Provide a default database and retention policy
|
||||
- **Token**: If [InfluxDB authentication is enabled](/enterprise_influxdb/v1/administration/authentication_and_authorization/)
|
||||
|
||||
```sh
|
||||
http://localhost:8086
|
||||
```
|
||||
{{< img-hd src="/img/influxdb3/enterprise-v1-grafana-product-dropdown-flux.png" alt="Flux configuration for InfluxDB Enterprise 1.x" />}}
|
||||
|
||||
3. Under **InfluxDB Details**, enter the following:
|
||||
Click **Save & Test**. Grafana attempts to connect to InfluxDB Enterprise and returns the result of the test.
|
||||
|
||||
- **Organization**: Provide an arbitrary value.
|
||||
- **Token**: If [InfluxDB authentication is enabled](/enterprise_influxdb/v1/administration/authentication_and_authorization/),
|
||||
provide your InfluxDB username and password using the following syntax:
|
||||
|
||||
```sh
|
||||
# Syntax
|
||||
username:password
|
||||
|
||||
# Example
|
||||
johndoe:mY5uP3rS3crE7pA5Sw0Rd
|
||||
```
|
||||
|
||||
If authentication is not enabled, leave blank.
|
||||
|
||||
- **Default Bucket**: Provide a default database and retention policy combination
|
||||
using the following syntax:
|
||||
|
||||
```sh
|
||||
# Syntax
|
||||
database-name/retention-policy-name
|
||||
|
||||
# Examples
|
||||
example-db/example-rp
|
||||
telegraf/autogen
|
||||
```
|
||||
|
||||
- **Min time interval**: [Grafana minimum time interval](https://grafana.com/docs/grafana/latest/features/datasources/influxdb/#min-time-interval).
|
||||
|
||||
{{< img-hd src="/img/influxdb/v1-tools-grafana-flux.png" />}}
|
||||
|
||||
3. Click **Save & Test**. Grafana attempts to connect to InfluxDB and returns
|
||||
the result of the test.
|
||||
{{% /tab-content %}}
|
||||
<!------------------------------ END FLUX CONTENT ----------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
## Query and visualize data
|
||||
|
||||
With your InfluxDB connection configured, use Grafana to query and visualize time series data.
|
||||
|
||||
### Query inspection in Grafana
|
||||
|
||||
To learn about query management and inspection in Grafana, see the
|
||||
[Grafana Explore documentation](https://grafana.com/docs/grafana/latest/explore/).
|
||||
|
||||
### Build visualizations with Grafana
|
||||
|
||||
For a comprehensive walk-through of creating visualizations with
|
||||
Grafana, see the [Grafana documentation](https://grafana.com/docs/grafana/latest/).
|
||||
|
|
|
|||
|
|
@ -12,8 +12,14 @@ related:
|
|||
- https://grafana.com/docs/, Grafana documentation
|
||||
- /influxdb/cloud/query-data/get-started/
|
||||
- /influxdb/cloud/query-data/influxql/
|
||||
- /flux/v0/get-started/, Get started with Flux
|
||||
alt_links:
|
||||
cloud-serverless: /influxdb3/cloud-serverless/visualize-data/grafana/
|
||||
v1: /influxdb/v1/tools/grafana/
|
||||
enterprise_v1: /enterprise_influxdb/v1/tools/grafana/
|
||||
v2: /influxdb/v2/tools/grafana/
|
||||
core: /influxdb3/core/visualize-data/grafana/
|
||||
enterprise: /influxdb3/enterprise/visualize-data/grafana/
|
||||
cloud-serverless: /influxdb3/cloud-serverless/process-data/visualize/grafana/
|
||||
cloud-dedicated: /influxdb3/cloud-dedicated/process-data/visualize/grafana/
|
||||
clustered: /influxdb3/clustered/process-data/visualize/grafana/
|
||||
source: /shared/influxdb-v2/tools/grafana.md
|
||||
|
|
|
|||
|
|
@ -1,136 +1,139 @@
|
|||
---
|
||||
title: Use Grafana with InfluxDB
|
||||
seotitle: Use Grafana with InfluxDB v1.11
|
||||
seotitle: Use Grafana with InfluxDB v1.x
|
||||
description: >
|
||||
Configure Grafana to query and visualize data from InfluxDB v1.11.
|
||||
Configure Grafana to query and visualize data from InfluxDB v1.x.
|
||||
menu:
|
||||
influxdb_v1:
|
||||
name: Grafana
|
||||
weight: 60
|
||||
parent: Tools
|
||||
related:
|
||||
- /flux/v0/get-started/, Get started with Flux
|
||||
alt_links:
|
||||
v2: /influxdb/v2/tools/grafana/
|
||||
core: /influxdb3/core/visualize-data/grafana/
|
||||
enterprise: /influxdb3/enterprise/visualize-data/grafana/
|
||||
cloud-serverless: /influxdb3/cloud-serverless/process-data/visualize/grafana/
|
||||
cloud-dedicated: /influxdb3/cloud-dedicated/process-data/visualize/grafana/
|
||||
clustered: /influxdb3/clustered/process-data/visualize/grafana/
|
||||
canonical: /influxdb/v2/tools/grafana/
|
||||
---
|
||||
|
||||
Use [Grafana](https://grafana.com/) or [Grafana Cloud](https://grafana.com/products/cloud/)
|
||||
to visualize data from your **InfluxDB v1.11** instance.
|
||||
to visualize data from your {{% product-name %}} instance.
|
||||
|
||||
{{% note %}}
|
||||
#### Required
|
||||
- The instructions in this guide require **Grafana Cloud** or **Grafana v10.3+**.
|
||||
For information about using InfluxDB with other versions of Grafana,
|
||||
see the [Grafana documentation](https://grafana.com/docs/grafana/latest/datasources/influxdb/).
|
||||
- To use **Flux**, use **InfluxDB 1.8.1+** and [enable Flux](/influxdb/v1/flux/installation/)
|
||||
in your InfluxDB configuration file.
|
||||
{{% /note %}}
|
||||
> [!Note]
|
||||
> {{< influxdb-version-detector >}}
|
||||
|
||||
1. [Start InfluxDB](/influxdb/v1/introduction/get-started/).
|
||||
2. [Sign up for Grafana Cloud](https://grafana.com/products/cloud/) or
|
||||
[download and install Grafana](https://grafana.com/grafana/download).
|
||||
3. Visit your **Grafana Cloud user interface** (UI) or, if running Grafana locally,
|
||||
[start Grafana](https://grafana.com/docs/grafana/latest/installation/) and visit
|
||||
<http://localhost:3000> in your browser.
|
||||
4. In the left navigation of the Grafana UI, expand the **Connections** section
|
||||
and click **Add new connection**.
|
||||
5. Select **InfluxDB** from the list of available data sources and click
|
||||
**Add data source**.
|
||||
6. On the **Data Source configuration page**, enter a **name** for your InfluxDB data source.
|
||||
7. In the **Query Language** drop-down menu, select one of the query languages
|
||||
supported by InfluxDB {{< current-version >}} (InfluxQL or Flux):
|
||||
> [!Note]
|
||||
> #### Required
|
||||
> - The instructions in this guide require **Grafana Cloud** or **Grafana v10.3+**.
|
||||
> For information about using InfluxDB with other versions of Grafana,
|
||||
> see the [Grafana documentation](https://grafana.com/docs/grafana/latest/datasources/influxdb/).
|
||||
> - To use **Flux**, use **InfluxDB 1.8.1+** and [enable Flux](/influxdb/v1/flux/installation/)
|
||||
> in your InfluxDB configuration file.
|
||||
|
||||
{{% note %}}
|
||||
SQL is only supported in InfluxDB 3.
|
||||
{{% /note %}}
|
||||
- [Install Grafana](#install-grafana)
|
||||
- [Create an InfluxDB data source](#create-an-influxdb-data-source)
|
||||
- [Query and visualize data](#query-and-visualize-data)
|
||||
|
||||
## Install Grafana
|
||||
|
||||
1. [Start InfluxDB](/influxdb/v1/introduction/get-started/).
|
||||
2. [Sign up for Grafana Cloud](https://grafana.com/products/cloud/) or
|
||||
[download and install Grafana](https://grafana.com/grafana/download).
|
||||
3. Visit your **Grafana Cloud user interface** (UI) or, if running Grafana locally,
|
||||
[start Grafana](https://grafana.com/docs/grafana/latest/installation/) and visit
|
||||
<http://localhost:3000> in your browser.
|
||||
|
||||
> [!Note]
|
||||
> #### Using Grafana Cloud with a local InfluxDB instance
|
||||
>
|
||||
> If you need to keep your database local, consider running Grafana locally instead of using Grafana Cloud,
|
||||
> as this avoids the need to expose your database to the internet.
|
||||
>
|
||||
> To use InfluxDB running on your private network with Grafana Cloud, you must
|
||||
> [configure a private data source](https://grafana.com/docs/grafana-cloud/data-sources/private-data-sources/).
|
||||
> See the Grafana documentation for instructions on configuring a Grafana Cloud private data source
|
||||
> with {{% product-name %}} running on `http://localhost:8086`.
|
||||
|
||||
> [!Note]
|
||||
> SQL is only supported in InfluxDB 3.
|
||||
> For more information, see how to [get started with InfluxDB 3 Core](/influxdb3/core/get-started/).
|
||||
|
||||
## Create an InfluxDB data source
|
||||
|
||||
1. In your Grafana interface, click **Connections** in the left sidebar
|
||||
2. Click **Data sources**
|
||||
3. Click **Add new connection**
|
||||
4. Search for and select **InfluxDB**. The InfluxDB data source configuration page displays.
|
||||
5. In the **Settings** tab, configure the following:
|
||||
|
||||
- **Name**: A descriptive name for your data source
|
||||
- **URL**: Your server URL--for example, `https://{{< influxdb/host >}}`
|
||||
- **Product**: From the dropdown, select **InfluxDB OSS 1.x**
|
||||
- **Query Language**: Select **InfluxQL** or **Flux**
|
||||
|
||||
### Configure database settings
|
||||
|
||||
The fields in this section change based on your query language selection.
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
[InfluxQL](#)
|
||||
[Flux](#)
|
||||
{{% /tabs %}}
|
||||
<!--------------------------- BEGIN INFLUXQL CONTENT -------------------------->
|
||||
{{% tab-content %}}
|
||||
<!--------------------------- BEGIN INFLUXQL CONTENT -------------------------->
|
||||
|
||||
## Configure Grafana to use InfluxQL
|
||||
|
||||
With **InfluxQL** selected as the query language in your InfluxDB data source settings:
|
||||
When you select **InfluxQL** as the query language, configure the following:
|
||||
|
||||
1. Under **HTTP**, enter the following:
|
||||
- **Database**: Your database name
|
||||
- **User**: Your InfluxDB username _(if [authentication is enabled](/influxdb/v1/administration/authentication_and_authorization/)); leave blank if authentication is disabled._
|
||||
- **Password**: Your InfluxDB password _(if [authentication is enabled](/influxdb/v1/administration/authentication_and_authorization/)); leave blank if authentication is disabled._
|
||||
|
||||
- **URL**: Your **InfluxDB URL**.
|
||||
{{< img-hd src="/img/influxdb3/OSS-v1-grafana-product-dropdown-influxql.png" alt="InfluxQL configuration for InfluxDB OSS 1.x" />}}
|
||||
|
||||
```sh
|
||||
http://localhost:8086
|
||||
```
|
||||
Click **Save & Test**. Grafana attempts to connect to InfluxDB and returns the result of the test.
|
||||
|
||||
2. Under **InfluxDB Details**, enter the following:
|
||||
|
||||
- **Database**: your database name
|
||||
- **User**: your InfluxDB username _(if [authentication is enabled](/influxdb/v1/administration/authentication_and_authorization/))_
|
||||
- **Password**: your InfluxDB password _(if [authentication is enabled](/influxdb/v1/administration/authentication_and_authorization/))_
|
||||
- **HTTP Method**: Select **GET** or **POST** _(for differences between the two,
|
||||
see the [query HTTP endpoint documentation](/influxdb/v1/tools/api/#query-http-endpoint))_
|
||||
|
||||
3. Provide a **[Min time interval](https://grafana.com/docs/grafana/latest/datasources/influxdb/#min-time-interval)**
|
||||
(default is 10s).
|
||||
|
||||
{{< img-hd src="/img/influxdb/v1-tools-grafana-influxql.png" />}}
|
||||
|
||||
4. Click **Save & Test**. Grafana attempts to connect to InfluxDB and returns
|
||||
the result of the test.
|
||||
|
||||
{{% /tab-content %}}
|
||||
<!---------------------------- END INFLUXQL CONTENT --------------------------->
|
||||
<!----------------------------- BEGIN FLUX CONTENT ---------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{% tab-content %}}
|
||||
<!----------------------------- BEGIN FLUX CONTENT ---------------------------->
|
||||
|
||||
## Configure Grafana to use Flux
|
||||
|
||||
With **Flux** selected as the query language in your InfluxDB data source,
|
||||
configure your InfluxDB connection:
|
||||
When you select **Flux** as the query language, configure the following:
|
||||
|
||||
1. Ensure [Flux is enabled](/influxdb/v1/flux/installation/) in InfluxDB.
|
||||
1. Ensure [Flux is enabled](/influxdb/v1/flux/installation/) in your InfluxDB configuration file.
|
||||
|
||||
2. Under **HTTP**, enter the following:
|
||||
2. Configure the database settings:
|
||||
|
||||
- **URL**: Your **InfluxDB URL**.
|
||||
- **Organization**: Provide an arbitrary value (InfluxDB 1.x does not use organizations)
|
||||
- **Default Bucket**: Provide a default database and retention policy
|
||||
- **Token**: If [InfluxDB authentication is enabled](/influxdb/v1/administration/authentication_and_authorization/) provide your InfluxDB username and password
|
||||
|
||||
```sh
|
||||
http://localhost:8086
|
||||
```
|
||||
{{< img-hd src="/img/influxdb3/OSS-v1-grafana-product-dropdown-flux.png" alt="Flux configuration for InfluxDB OSS 1.x" />}}
|
||||
|
||||
3. Under **InfluxDB Details**, enter the following:
|
||||
Click **Save & Test**. Grafana attempts to connect to InfluxDB and returns the result of the test.
|
||||
|
||||
- **Organization**: Provide an arbitrary value.
|
||||
- **Token**: If [InfluxDB authentication is enabled](/influxdb/v1/administration/authentication_and_authorization/),
|
||||
provide your InfluxDB username and password using the following syntax:
|
||||
|
||||
```sh
|
||||
# Syntax
|
||||
username:password
|
||||
|
||||
# Example
|
||||
johndoe:mY5uP3rS3crE7pA5Sw0Rd
|
||||
```
|
||||
|
||||
If authentication is not enabled, leave blank.
|
||||
|
||||
- **Default Bucket**: Provide a default database and retention policy combination
|
||||
using the following syntax:
|
||||
|
||||
```sh
|
||||
# Syntax
|
||||
database-name/retention-policy-name
|
||||
|
||||
# Examples
|
||||
example-db/example-rp
|
||||
telegraf/autogen
|
||||
```
|
||||
|
||||
- **Min time interval**: [Grafana minimum time interval](https://grafana.com/docs/grafana/latest/features/datasources/influxdb/#min-time-interval).
|
||||
|
||||
{{< img-hd src="/img/influxdb/v1-tools-grafana-flux.png" />}}
|
||||
|
||||
3. Click **Save & Test**. Grafana attempts to connect to InfluxDB and returns
|
||||
the result of the test.
|
||||
{{% /tab-content %}}
|
||||
<!------------------------------ END FLUX CONTENT ----------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
## Query and visualize data
|
||||
|
||||
With your InfluxDB connection configured, use Grafana to query and visualize time series data.
|
||||
|
||||
### Query inspection in Grafana
|
||||
|
||||
To learn about query management and inspection in Grafana, see the
|
||||
[Grafana Explore documentation](https://grafana.com/docs/grafana/latest/explore/).
|
||||
|
||||
### Build visualizations with Grafana
|
||||
|
||||
For a comprehensive walk-through of creating visualizations with
|
||||
Grafana, see the [Grafana documentation](https://grafana.com/docs/grafana/latest/).
|
||||
|
|
|
|||
|
|
@ -13,6 +13,15 @@ aliases:
|
|||
related:
|
||||
- https://grafana.com/docs/, Grafana documentation
|
||||
- /influxdb/v2/query-data/get-started/
|
||||
alt_links:
|
||||
v1: /influxdb/v1/tools/grafana/
|
||||
enterprise_v1: /enterprise_influxdb/v1/tools/grafana/
|
||||
cloud: /influxdb/cloud/tools/grafana/
|
||||
core: /influxdb3/core/visualize-data/grafana/
|
||||
enterprise: /influxdb3/enterprise/visualize-data/grafana/
|
||||
cloud-serverless: /influxdb3/cloud-serverless/process-data/visualize/grafana/
|
||||
cloud-dedicated: /influxdb3/cloud-dedicated/process-data/visualize/grafana/
|
||||
clustered: /influxdb3/clustered/process-data/visualize/grafana/
|
||||
source: /shared/influxdb-v2/tools/grafana.md
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ menu:
|
|||
name: Use Chronograf
|
||||
parent: Visualize data
|
||||
weight: 202
|
||||
aliases:
|
||||
- /influxdb3/cloud-dedicated/visualize-data/chronograf/
|
||||
related:
|
||||
- /chronograf/v1/
|
||||
metadata: [InfluxQL only]
|
||||
|
|
@ -84,14 +86,14 @@ If you haven't already, [download and install Chronograf](/chronograf/v1/introdu
|
|||
> schema information may not be available in the Data Explorer.
|
||||
> This limits the Data Explorer's query building functionality and requires you to
|
||||
> build queries manually using
|
||||
> [fully-qualified measurements](/influxdb3/cloud-dedicated/reference/influxql/select/#fully-qualified-measurement)
|
||||
> [fully qualified measurements](/influxdb3/cloud-dedicated/reference/influxql/select/#fully-qualified-measurement)
|
||||
> in the `FROM` clause. For example:
|
||||
>
|
||||
> ```sql
|
||||
> -- Fully-qualified measurement
|
||||
> -- Fully qualified measurement
|
||||
> SELECT * FROM "db-name"."rp-name"."measurement-name"
|
||||
>
|
||||
> -- Fully-qualified measurement shorthand (use the default retention policy)
|
||||
>
|
||||
> -- Fully qualified measurement shorthand (use the default retention policy)
|
||||
> SELECT * FROM "db-name".."measurement-name"
|
||||
> ```
|
||||
>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ aliases:
|
|||
- /influxdb3/cloud-dedicated/query-data/sql/execute-queries/grafana/
|
||||
- /influxdb3/cloud-dedicated/query-data/influxql/execute-queries/grafana
|
||||
- /influxdb3/cloud-dedicated/process-data/tools/grafana/
|
||||
- /influxdb3/cloud-dedicated/visualize-data/grafana/
|
||||
alt_links:
|
||||
v2: /influxdb/v2/tools/grafana/
|
||||
cloud: /influxdb/cloud/tools/grafana/
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ menu:
|
|||
influxdb3/cloud-dedicated/tags: [Flight client, query, flightsql, superset]
|
||||
aliases:
|
||||
- /influxdb3/cloud-dedicated/query-data/execute-queries/flight-sql/superset/
|
||||
- /influxdb3/cloud-dedicated/visualize-data/superset/
|
||||
- /influxdb3/cloud-dedicated/query-data/tools/superset/
|
||||
- /influxdb3/cloud-dedicated/query-data/sql/execute-queries/superset/
|
||||
- /influxdb3/cloud-dedicated/process-data/tools/superset/
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ menu:
|
|||
influxdb3/cloud-dedicated/tags: [Flight client, query, flightsql, tableau, sql]
|
||||
aliases:
|
||||
- /influxdb3/cloud-dedicated/query-data/execute-queries/flight-sql/tableau/
|
||||
- /influxdb3/cloud-dedicated/visualize-data/tableau/
|
||||
- /influxdb3/cloud-dedicated/query-data/tools/tableau/
|
||||
- /influxdb3/cloud-dedicated/query-data/sql/execute-queries/tableau/
|
||||
- /influxdb3/cloud-dedicated/process-data/tools/tableau/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Execute SQL queries with ODBC
|
||||
description: >
|
||||
Use the Arrow Flight SQL ODBC driver to execute SQL queries against {{% product-name %}} from
|
||||
ODBC-compatible applications and programming languages.
|
||||
menu:
|
||||
influxdb3_cloud_dedicated:
|
||||
name: Use ODBC
|
||||
parent: Execute queries
|
||||
weight: 351
|
||||
influxdb3/cloud-dedicated/tags: [query, sql, odbc]
|
||||
metadata: [SQL]
|
||||
|
||||
related:
|
||||
- /influxdb3/cloud-dedicated/reference/sql/
|
||||
- /influxdb3/cloud-dedicated/query-data/
|
||||
source: /shared/influxdb3-query-guides/execute-queries/odbc.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-query-guides/execute-queries/odbc.md -->
|
||||
|
|
@ -9,7 +9,7 @@ menu:
|
|||
parent: Execute queries
|
||||
name: Use visualization tools
|
||||
identifier: query-with-visualization-tools
|
||||
influxdb3/cloud-dedicated/tags: [query, sql, influxql]
|
||||
influxdb3/cloud-dedicated/tags: [query, sql, influxql, visualization]
|
||||
metadata: [SQL, InfluxQL]
|
||||
aliases:
|
||||
- /influxdb3/cloud-dedicated/query-data/influxql/execute-queries/visualization-tools/
|
||||
|
|
@ -27,6 +27,7 @@ Use visualization tools to query data stored in {{% product-name %}} with SQL.
|
|||
The following visualization tools support querying InfluxDB with SQL:
|
||||
|
||||
- [Grafana](/influxdb3/cloud-dedicated/process-data/visualize/grafana/)
|
||||
- [Power BI](/influxdb3/cloud-dedicated/process-data/visualize/powerbi/)
|
||||
- [Superset](/influxdb3/cloud-dedicated/process-data/visualize/superset/)
|
||||
- [Tableau](/influxdb3/cloud-dedicated/process-data/visualize/tableau/)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Use Power BI to visualize data
|
||||
description: >
|
||||
Use Microsoft Power BI Desktop with the InfluxDB 3 custom connector to query and
|
||||
visualize data from {{% product-name %}}.
|
||||
menu:
|
||||
influxdb3_cloud_dedicated:
|
||||
name: Power BI
|
||||
parent: Visualize data
|
||||
weight: 104
|
||||
influxdb3/cloud-dedicated/tags: [visualization, powerbi, sql]
|
||||
metadata: [SQL]
|
||||
related:
|
||||
- https://learn.microsoft.com/en-us/power-bi/desktop/, Power BI documentation
|
||||
- /influxdb3/cloud-dedicated/query-data/sql/
|
||||
- /influxdb3/cloud-dedicated/query-data/execute-queries/odbc/
|
||||
source: /shared/influxdb3-visualize/powerbi.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-visualize/powerbi.md -->
|
||||
|
|
@ -9,6 +9,8 @@ menu:
|
|||
name: Use Chronograf
|
||||
parent: Visualize data
|
||||
weight: 202
|
||||
aliases:
|
||||
- /influxdb3/cloud-serverless/visualize-data/chronograf/
|
||||
related:
|
||||
- /chronograf/v1/
|
||||
metadata: [InfluxQL only]
|
||||
|
|
@ -77,14 +79,14 @@ If you haven't already, [download and install Chronograf](/chronograf/v1/introdu
|
|||
> schema information may not be available in the Data Explorer.
|
||||
> This limits the Data Explorer's query building functionality and requires you to
|
||||
> build queries manually using
|
||||
> [fully-qualified measurements](/influxdb3/cloud-serverless/reference/influxql/select/#fully-qualified-measurement)
|
||||
> [fully qualified measurements](/influxdb3/cloud-serverless/reference/influxql/select/#fully-qualified-measurement)
|
||||
> in the `FROM` clause. For example:
|
||||
>
|
||||
> ```sql
|
||||
> -- Fully-qualified measurement
|
||||
> -- Fully qualified measurement
|
||||
> SELECT * FROM "db-name"."rp-name"."measurement-name"
|
||||
>
|
||||
> -- Fully-qualified measurement shorthand (use the default retention policy)
|
||||
>
|
||||
> -- Fully qualified measurement shorthand (use the default retention policy)
|
||||
> SELECT * FROM "db-name".."measurement-name"
|
||||
> ```
|
||||
>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ influxdb3/cloud-serverless/tags: [Flight client, query, flightsql, superset]
|
|||
aliases:
|
||||
- /influxdb3/cloud-serverless/query-data/tools/superset/
|
||||
- /influxdb3/cloud-serverless/query-data/sql/execute-queries/superset/
|
||||
- /influxdb3/cloud-serverless/visualize-data/superset/
|
||||
- /influxdb3/cloud-serverless/process-data/tools/superset/
|
||||
alt_links:
|
||||
core: /influxdb3/core/visualize-data/superset/
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ menu:
|
|||
influxdb3/cloud-serverless/tags: [Flight client, query, flightsql, tableau, sql]
|
||||
aliases:
|
||||
- /influxdb3/cloud-serverless/query-data/sql/execute-queries/tableau/
|
||||
- /influxdb3/cloud-serverless/visualize-data/tableau/
|
||||
alt_links:
|
||||
core: /influxdb3/core/visualize-data/tableau/
|
||||
enterprise: /influxdb3/enterprise/visualize-data/tableau/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
title: Execute SQL queries with ODBC
|
||||
description: >
|
||||
Use the Arrow Flight SQL ODBC driver to execute SQL queries against {{% product-name %}} from
|
||||
ODBC-compatible applications and programming languages.
|
||||
menu:
|
||||
influxdb3_cloud_serverless:
|
||||
name: Use ODBC
|
||||
parent: Execute queries
|
||||
weight: 351
|
||||
influxdb3/cloud-serverless/tags: [query, sql, odbc]
|
||||
metadata: [SQL]
|
||||
related:
|
||||
- /influxdb3/cloud-serverless/reference/sql/
|
||||
- /influxdb3/cloud-serverless/query-data/
|
||||
source: /shared/influxdb3-query-guides/execute-queries/odbc.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-query-guides/execute-queries/odbc.md -->
|
||||
|
|
@ -9,7 +9,7 @@ menu:
|
|||
parent: Execute queries
|
||||
name: Use visualization tools
|
||||
identifier: query-with-visualization-tools
|
||||
influxdb3/cloud-serverless/tags: [query, sql, influxql]
|
||||
influxdb3/cloud-serverless/tags: [query, sql, influxql, visualization]
|
||||
metadata: [SQL, InfluxQL]
|
||||
aliases:
|
||||
- /influxdb3/cloud-serverless/query-data/influxql/execute-queries/visualization-tools/
|
||||
|
|
@ -27,6 +27,7 @@ Use visualization tools to query data stored in {{% product-name %}}.
|
|||
The following visualization tools support querying InfluxDB with SQL:
|
||||
|
||||
- [Grafana](/influxdb3/cloud-serverless/process-data/visualize/grafana/)
|
||||
- [Power BI](/influxdb3/cloud-serverless/process-data/visualize/powerbi/)
|
||||
- [Superset](/influxdb3/cloud-serverless/process-data/visualize/superset/)
|
||||
- [Tableau](/influxdb3/cloud-serverless/process-data/visualize/tableau/)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Use Power BI to visualize data
|
||||
description: >
|
||||
Use Microsoft Power BI Desktop with the InfluxDB 3 custom connector to query and
|
||||
visualize data from {{% product-name %}}.
|
||||
menu:
|
||||
influxdb3_cloud_serverless:
|
||||
name: Power BI
|
||||
parent: Visualize data
|
||||
weight: 104
|
||||
influxdb3/cloud-serverless/tags: [visualization, powerbi, sql]
|
||||
metadata: [SQL]
|
||||
related:
|
||||
- https://learn.microsoft.com/en-us/power-bi/desktop/, Power BI documentation
|
||||
- /influxdb3/cloud-serverless/query-data/sql/
|
||||
- /influxdb3/cloud-serverless/query-data/execute-queries/odbc/
|
||||
source: /shared/influxdb3-visualize/powerbi.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-visualize/powerbi.md -->
|
||||
|
|
@ -9,6 +9,8 @@ menu:
|
|||
name: Use Chronograf
|
||||
parent: Visualize data
|
||||
weight: 202
|
||||
aliases:
|
||||
- /influxdb3/clustered/visualize-data/chronograf/
|
||||
related:
|
||||
- /chronograf/v1/
|
||||
metadata: [InfluxQL only]
|
||||
|
|
@ -84,14 +86,14 @@ If you haven't already, [download and install Chronograf](/chronograf/v1/introdu
|
|||
> schema information may not be available in the Data Explorer.
|
||||
> This limits the Data Explorer's query building functionality and requires you to
|
||||
> build queries manually using
|
||||
> [fully-qualified measurements](/influxdb3/clustered/reference/influxql/select/#fully-qualified-measurement)
|
||||
> [fully qualified measurements](/influxdb3/clustered/reference/influxql/select/#fully-qualified-measurement)
|
||||
> in the `FROM` clause. For example:
|
||||
>
|
||||
> ```sql
|
||||
> -- Fully-qualified measurement
|
||||
> -- Fully qualified measurement
|
||||
> SELECT * FROM "db-name"."rp-name"."measurement-name"
|
||||
>
|
||||
> -- Fully-qualified measurement shorthand (use the default retention policy)
|
||||
>
|
||||
> -- Fully qualified measurement shorthand (use the default retention policy)
|
||||
> SELECT * FROM "db-name".."measurement-name"
|
||||
> ```
|
||||
>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ aliases:
|
|||
- /influxdb3/clustered/query-data/sql/execute-queries/grafana/
|
||||
- /influxdb3/clustered/query-data/influxql/execute-queries/grafana
|
||||
- /influxdb3/clustered/process-data/tools/grafana/
|
||||
- /influxdb3/clustered/visualize-data/grafana/
|
||||
alt_links:
|
||||
v2: /influxdb/v2/tools/grafana/
|
||||
cloud: /influxdb/cloud/tools/grafana/
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ menu:
|
|||
influxdb3/clustered/tags: [Flight client, query, flightsql, superset]
|
||||
aliases:
|
||||
- /influxdb3/clustered/query-data/execute-queries/flight-sql/superset/
|
||||
- /influxdb3/clustered/visualize-data/superset/
|
||||
- /influxdb3/clustered/query-data/tools/superset/
|
||||
- /influxdb3/clustered/query-data/sql/execute-queries/superset/
|
||||
- /influxdb3/clustered/process-data/tools/superset/
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ menu:
|
|||
influxdb3/clustered/tags: [Flight client, query, flightsql, tableau, sql]
|
||||
aliases:
|
||||
- /influxdb3/clustered/query-data/execute-queries/flight-sql/tableau/
|
||||
- /influxdb3/clustered/visualize-data/tableau/
|
||||
- /influxdb3/clustered/query-data/tools/tableau/
|
||||
- /influxdb3/clustered/query-data/sql/execute-queries/tableau/
|
||||
- /influxdb3/clustered/process-data/tools/tableau/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
title: Execute SQL queries with ODBC
|
||||
description: >
|
||||
Use the Arrow Flight SQL ODBC driver to execute SQL queries against {{% product-name %}} from
|
||||
ODBC-compatible applications and programming languages.
|
||||
menu:
|
||||
influxdb3_clustered:
|
||||
name: Use ODBC
|
||||
parent: Execute queries
|
||||
weight: 351
|
||||
influxdb3/clustered/tags: [query, sql, odbc]
|
||||
metadata: [SQL]
|
||||
related:
|
||||
- /influxdb3/clustered/reference/sql/
|
||||
- /influxdb3/clustered/query-data/
|
||||
source: /shared/influxdb3-query-guides/execute-queries/odbc.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-query-guides/execute-queries/odbc.md -->
|
||||
|
|
@ -9,7 +9,7 @@ menu:
|
|||
parent: Execute queries
|
||||
name: Use visualization tools
|
||||
identifier: query-with-visualization-tools
|
||||
influxdb3/clustered/tags: [query, sql, influxql]
|
||||
influxdb3/clustered/tags: [query, sql, influxql, visualization]
|
||||
metadata: [SQL, InfluxQL]
|
||||
aliases:
|
||||
- /influxdb3/clustered/query-data/influxql/execute-queries/visualization-tools/
|
||||
|
|
@ -27,6 +27,7 @@ Use visualization tools to query data stored in {{% product-name %}} with SQL.
|
|||
The following visualization tools support querying InfluxDB with SQL:
|
||||
|
||||
- [Grafana](/influxdb3/clustered/process-data/visualize/grafana/)
|
||||
- [Power BI](/influxdb3/clustered/process-data/visualize/powerbi/)
|
||||
- [Superset](/influxdb3/clustered/process-data/visualize/superset/)
|
||||
- [Tableau](/influxdb3/clustered/process-data/visualize/tableau/)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Use Power BI to visualize data
|
||||
description: >
|
||||
Use Microsoft Power BI Desktop with the InfluxDB 3 custom connector to query and
|
||||
visualize data from {{% product-name %}}.
|
||||
menu:
|
||||
influxdb3_clustered:
|
||||
name: Power BI
|
||||
parent: Visualize data
|
||||
weight: 104
|
||||
influxdb3/clustered/tags: [visualization, powerbi, sql]
|
||||
metadata: [SQL]
|
||||
related:
|
||||
- https://learn.microsoft.com/en-us/power-bi/desktop/, Power BI documentation
|
||||
- /influxdb3/clustered/query-data/sql/
|
||||
- /influxdb3/clustered/query-data/execute-queries/odbc/
|
||||
source: /shared/influxdb3-visualize/powerbi.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-visualize/powerbi.md -->
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Execute SQL queries with ODBC
|
||||
description: >
|
||||
Use the Arrow Flight SQL ODBC driver to execute SQL queries against {{% product-name %}} from
|
||||
ODBC-compatible applications and programming languages.
|
||||
menu:
|
||||
influxdb3_core:
|
||||
name: Use ODBC
|
||||
parent: Execute queries
|
||||
weight: 351
|
||||
influxdb3/core/tags: [query, sql, odbc]
|
||||
metadata: [SQL]
|
||||
related:
|
||||
- /influxdb3/core/reference/sql/
|
||||
- /influxdb3/core/query-data/
|
||||
- /influxdb3/core/visualize-data/powerbi/
|
||||
source: /shared/influxdb3-query-guides/execute-queries/odbc.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-query-guides/execute-queries/odbc.md -->
|
||||
|
|
@ -11,15 +11,15 @@ menu:
|
|||
parent: Visualize data
|
||||
influxdb3/core/tags: [query, visualization]
|
||||
alt_links:
|
||||
v1: /influxdb/v1/tools/grafana/
|
||||
v2: /influxdb/v2/tools/grafana/
|
||||
cloud: /influxdb/cloud/tools/grafana/
|
||||
enterprise: /influxdb3/enterprise/visualize-data/grafana/
|
||||
enterprise_v1: /enterprise_influxdb/v1/tools/grafana/
|
||||
cloud-serverless: /influxdb3/cloud-serverless/process-data/visualize/grafana/
|
||||
cloud-dedicated: /influxdb3/cloud-dedicated/process-data/visualize/grafana/
|
||||
clustered: /influxdb3/clustered/process-data/visualize/grafana/
|
||||
source: /shared/influxdb3-visualize/grafana.md
|
||||
v1: /influxdb/v1/tools/grafana/
|
||||
v2: /influxdb/v2/tools/grafana/
|
||||
cloud: /influxdb/cloud/tools/grafana/
|
||||
source: /content/shared/v3-process-data/visualize/grafana.md
|
||||
---
|
||||
|
||||
<!--
|
||||
The content of this page is at content/shared/influxdb3-visualize/grafana.md
|
||||
-->
|
||||
<!-- SOURCE: /content/shared/v3-process-data/visualize/grafana.md -->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Use Power BI to visualize data
|
||||
description: >
|
||||
Use Microsoft Power BI Desktop with the InfluxDB 3 custom connector to query and
|
||||
visualize data from {{% product-name %}}.
|
||||
menu:
|
||||
influxdb3_core:
|
||||
name: Power BI
|
||||
parent: Visualize data
|
||||
weight: 104
|
||||
influxdb3/core/tags: [visualization, powerbi, sql]
|
||||
metadata: [SQL]
|
||||
related:
|
||||
- https://learn.microsoft.com/en-us/power-bi/desktop/, Power BI documentation
|
||||
- /influxdb3/core/query-data/sql/
|
||||
- /influxdb3/core/query-data/execute-queries/odbc/
|
||||
source: /shared/influxdb3-visualize/powerbi.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-visualize/powerbi.md -->
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Execute SQL queries with ODBC
|
||||
description: >
|
||||
Use the Arrow Flight SQL ODBC driver to execute SQL queries against {{% product-name %}} from
|
||||
ODBC-compatible applications and programming languages.
|
||||
menu:
|
||||
influxdb3_enterprise:
|
||||
name: Use ODBC
|
||||
parent: Execute queries
|
||||
weight: 351
|
||||
influxdb3/enterprise/tags: [query, sql, odbc]
|
||||
metadata: [SQL]
|
||||
related:
|
||||
- /influxdb3/enterprise/reference/sql/
|
||||
- /influxdb3/enterprise/query-data/
|
||||
- /influxdb3/enterprise/visualize-data/powerbi/
|
||||
source: /shared/influxdb3-query-guides/execute-queries/odbc.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-query-guides/execute-queries/odbc.md -->
|
||||
|
|
@ -11,15 +11,15 @@ menu:
|
|||
parent: Visualize data
|
||||
influxdb3/enterprise/tags: [query, visualization]
|
||||
alt_links:
|
||||
v1: /influxdb/v1/tools/grafana/
|
||||
v2: /influxdb/v2/tools/grafana/
|
||||
cloud: /influxdb/cloud/tools/grafana/
|
||||
core: /influxdb3/core/visualize-data/grafana/
|
||||
cloud-serverless: /influxdb3/cloud-serverless/process-data/visualize/grafana/
|
||||
cloud-dedicated: /influxdb3/cloud-dedicated/process-data/visualize/grafana/
|
||||
clustered: /influxdb3/clustered/process-data/visualize/grafana/
|
||||
source: /shared/influxdb3-visualize/grafana.md
|
||||
enterprise_v1: /enterprise_influxdb/v1/tools/grafana/
|
||||
v1: /influxdb/v1/tools/grafana/
|
||||
v2: /influxdb/v2/tools/grafana/
|
||||
cloud: /influxdb/cloud/tools/grafana/
|
||||
source: /content/shared/v3-process-data/visualize/grafana.md
|
||||
---
|
||||
|
||||
<!--
|
||||
The content of this page is at content/shared/influxdb3-visualize/grafana.md
|
||||
-->
|
||||
<!-- SOURCE: /content/shared/v3-process-data/visualize/grafana.md -->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
title: Use Power BI to visualize data
|
||||
description: >
|
||||
Use Microsoft Power BI Desktop with the InfluxDB 3 custom connector to query and
|
||||
visualize data from {{% product-name %}}.
|
||||
menu:
|
||||
influxdb3_enterprise:
|
||||
name: Power BI
|
||||
parent: Visualize data
|
||||
weight: 104
|
||||
influxdb3/enterprise/tags: [visualization, powerbi, sql]
|
||||
metadata: [SQL]
|
||||
related:
|
||||
- https://learn.microsoft.com/en-us/power-bi/desktop/, Power BI documentation
|
||||
- /influxdb3/enterprise/query-data/sql/
|
||||
- /influxdb3/enterprise/query-data/execute-queries/odbc/
|
||||
source: /shared/influxdb3-visualize/powerbi.md
|
||||
---
|
||||
|
||||
<!-- //SOURCE content/shared/influxdb3-visualize/powerbi.md -->
|
||||
|
|
@ -14,6 +14,14 @@ Using InfluxDB 3's IOx-specific Flight RPC protocol, clients send a single `DoGe
|
|||
**Flight SQL clients** use the [Flight SQL protocol](https://arrow.apache.org/docs/format/FlightSql.html) for querying an SQL database server.
|
||||
They can use SQL to query data stored in an {{% product-name %}} database, but they can't use InfuxQL.
|
||||
|
||||
> [!Important]
|
||||
> #### Flight SQL requires HTTP/2
|
||||
>
|
||||
> Flight SQL uses gRPC, which requires **HTTP/2**.
|
||||
> If you connect to {{% product-name %}} through a proxy (such as HAProxy, nginx, or a load balancer),
|
||||
> verify that your proxy is configured to support HTTP/2.
|
||||
> Without HTTP/2 support, Flight SQL connections will fail.
|
||||
|
||||
Clients are maintained by Apache Arrow projects or third-parties.
|
||||
For specifics about a Flight client, see the client's GitHub repository.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,70 @@
|
|||
Use [Grafana](https://grafana.com/) or [Grafana Cloud](https://grafana.com/products/cloud/)
|
||||
to visualize data from your **InfluxDB {{< current-version >}}** instance.
|
||||
|
||||
{{% note %}}
|
||||
The instructions in this guide require **Grafana Cloud** or **Grafana 10.3+**.
|
||||
{{% /note %}}
|
||||
> [!Note]
|
||||
> {{< influxdb-version-detector >}}
|
||||
|
||||
1. {{% show-in "cloud,cloud-serverless" %}}[Log into InfluxDB Cloud](https://cloud2.influxdata.com).{{% /show-in %}}
|
||||
{{% show-in "v2" %}}[Start InfluxDB](/influxdb/version/install/#configure-and-start-influxdb).{{% /show-in %}}
|
||||
2. [Sign up for Grafana Cloud](https://grafana.com/products/cloud/) or
|
||||
[download and install Grafana](https://grafana.com/grafana/download).
|
||||
3. Visit your **Grafana Cloud user interface** (UI) or, if running Grafana locally,
|
||||
[start Grafana](https://grafana.com/docs/grafana/latest/installation/) and visit
|
||||
<http://localhost:3000> in your browser.
|
||||
4. In the left navigation of the Grafana UI, open the **Connections** section
|
||||
and select **Add new connection**.
|
||||
5. Select **InfluxDB** from the list of available data sources and click
|
||||
**Add new data source**.
|
||||
6. On the **Data Source configuration page**, enter a **name** for your InfluxDB data source.
|
||||
7. In the **Query Language** drop-down menu, select one of the query languages
|
||||
supported by InfluxDB {{< current-version >}} (Flux or InfluxQL):
|
||||
> [!Note]
|
||||
> The instructions in this guide require **Grafana Cloud** or **Grafana 10.3+**.
|
||||
|
||||
{{% note %}}
|
||||
SQL is only supported in InfluxDB 3.
|
||||
{{% /note %}}
|
||||
- [Install Grafana](#install-grafana)
|
||||
- [Create an InfluxDB data source](#create-an-influxdb-data-source)
|
||||
- [Query and visualize data](#query-and-visualize-data)
|
||||
|
||||
## Install Grafana
|
||||
|
||||
1. [Start InfluxDB OSS 2.x](/influxdb/v2/install/#configure-and-start-influxdb).
|
||||
2. [Sign up for Grafana Cloud](https://grafana.com/products/cloud/) or
|
||||
[download and install Grafana](https://grafana.com/grafana/download).
|
||||
3. Visit your **Grafana Cloud user interface** (UI) or, if running Grafana locally,
|
||||
[start Grafana](https://grafana.com/docs/grafana/latest/installation/) and visit
|
||||
<http://localhost:3000> in your browser.
|
||||
|
||||
{{% show-in "v2" %}}
|
||||
> [!Note]
|
||||
> #### Using Grafana Cloud with a local InfluxDB instance
|
||||
>
|
||||
> If you need to keep your database local, consider running Grafana locally instead of using Grafana Cloud,
|
||||
> as this avoids the need to expose your database to the internet.
|
||||
>
|
||||
> To use InfluxDB running on your private network with Grafana Cloud, you must
|
||||
> [configure a private data source](https://grafana.com/docs/grafana-cloud/data-sources/private-data-sources/).
|
||||
> See the Grafana documentation for instructions on configuring a Grafana Cloud private data source
|
||||
> with {{% product-name %}} running on `http://localhost:8086`.
|
||||
{{% /show-in %}}
|
||||
|
||||
> [!Note]
|
||||
> SQL is only supported in InfluxDB 3.
|
||||
> {{% show-in "v2" %}}For more information, see how to [get-started with InfluxDB 3 Core](/influxdb3/core/get-started/).{{% /show-in %}}{{% show-in "cloud" %}}For more information, see how to upgrade to [InfluxDB Cloud Serverless](/influxdb/cloud/upgrade/v2-to-cloud/).{{% /show-in %}}
|
||||
|
||||
## Quick reference
|
||||
|
||||
| Configuration | Value |
|
||||
|:------------- |:----- |
|
||||
| **Product selection** | {{% show-in "v2" %}}**InfluxDB OSS 2.x**{{% /show-in %}}{{% show-in "cloud" %}}**InfluxDB Cloud (TSM)**{{% /show-in %}} |
|
||||
| **URL** | {{% show-in "v2" %}}[Server URL](/influxdb/v2/reference/urls/)--for example, `https://{{< influxdb/host >}}`{{% /show-in %}}{{% show-in "cloud" %}}[Region URL](/influxdb/cloud/reference/regions/)--for example, `https://us-east-2-1.aws.cloud2.influxdata.com`{{% /show-in %}} |
|
||||
| **Query languages** | Flux, InfluxQL |
|
||||
| **Authentication** | API token or v1 username/password |
|
||||
| **Organization** | Organization name or ID (Flux only) |
|
||||
| **Default Bucket** | Default bucket for Flux queries (Flux only) |
|
||||
| **Database** | Database name mapped to bucket (InfluxQL only) |
|
||||
|
||||
## Create an InfluxDB data source
|
||||
|
||||
1. In your Grafana interface, click **Connections** in the left sidebar
|
||||
2. Click **Data sources**
|
||||
3. Click **Add new connection**
|
||||
4. Search for and select **InfluxDB**. The InfluxDB data source configuration page displays.
|
||||
5. In the **Settings** tab, configure the following:
|
||||
|
||||
- **Name**: A descriptive name for your data source
|
||||
- **URL**: Your {{% show-in "v2" %}}[server URL](/influxdb/v2/reference/urls/)--for example, `https://{{< influxdb/host >}}`{{% /show-in %}}{{% show-in "cloud" %}}[region URL](/influxdb/cloud/reference/regions/)--for example, `https://us-east-2-1.aws.cloud2.influxdata.com`{{% /show-in %}}
|
||||
- **Product**: From the dropdown, select {{% show-in "v2" %}}**InfluxDB OSS 2.x**{{% /show-in %}}{{% show-in "cloud" %}}**InfluxDB Cloud (TSM)**{{% /show-in %}}
|
||||
- **Query Language**: Select **Flux** or **InfluxQL**
|
||||
|
||||
### Configure database settings
|
||||
|
||||
The fields in this section change based on your query language selection.
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
|
|
@ -30,330 +72,136 @@ SQL is only supported in InfluxDB 3.
|
|||
[InfluxQL](#)
|
||||
{{% /tabs %}}
|
||||
{{% tab-content %}}
|
||||
<!--------------------------------- BEGIN FLUX --------------------------------->
|
||||
|
||||
## Configure Grafana to use Flux
|
||||
|
||||
With **Flux** selected as the query language in your InfluxDB data source,
|
||||
configure your InfluxDB connection:
|
||||
When you select **Flux** as the query language, configure the following:
|
||||
|
||||
1. Under **HTTP**, enter the following:
|
||||
- **Organization**: Your InfluxDB [organization name or ID](/influxdb/v2/admin/organizations/view-orgs/)
|
||||
- **Default Bucket**: The default [bucket](/influxdb/v2/admin/buckets/) to use in Flux queries
|
||||
- **Token**: Your InfluxDB [API token](/influxdb/v2/admin/tokens/)
|
||||
|
||||
- **URL**: Your
|
||||
{{% show-in "v2" %}}[InfluxDB URL](/influxdb/version/reference/urls/).{{% /show-in %}}
|
||||
{{% show-in "cloud,cloud-serverless" %}}[InfluxDB Cloud region URL](/influxdb/version/reference/regions/).{{% /show-in %}}
|
||||
{{% show-in "v2" %}}{{< img-hd src="/img/influxdb/OSS-v2-grafana-product-dropdown-flux.png" alt="Flux configuration for InfluxDB OSS 2.x" />}}{{% /show-in %}}
|
||||
{{% show-in "cloud" %}}{{< img-hd src="/img/influxdb/influxdb-v2-cloud-flux.png" alt="Flux configuration for InfluxDB Cloud (TSM)" />}}{{% /show-in %}}
|
||||
|
||||
```sh
|
||||
http://localhost:8086/
|
||||
```
|
||||
|
||||
2. Under **InfluxDB Details**, enter the following:
|
||||
|
||||
- **Organization**: Your InfluxDB [organization name **or** ID](/influxdb/version/admin/organizations/view-orgs/).
|
||||
- **Token**: Your InfluxDB [API token](/influxdb/version/admin/tokens/).
|
||||
- **Default Bucket**: The default [bucket](/influxdb/version/admin/buckets/) to
|
||||
use in Flux queries.
|
||||
- **Min time interval**: The [Grafana minimum time interval](https://grafana.com/docs/grafana/latest/features/datasources/influxdb/#min-time-interval).
|
||||
Default is `10s`
|
||||
- **Max series**: The maximum number of series or tables Grafana will process.
|
||||
Default is `1000`.
|
||||
|
||||
3. Click **Save & Test**. Grafana attempts to connect to the InfluxDB {{< current-version >}}
|
||||
datasource and returns the results of the test.
|
||||
|
||||
{{% show-in "cloud,cloud-serverless" %}}
|
||||
{{< img-hd src="/img/influxdb/cloud-tools-grafana-flux.png" alt="Use Grafana with InfluxDB Cloud and Flux" />}}
|
||||
{{% /show-in %}}
|
||||
|
||||
{{% show-in "v2" %}}
|
||||
{{< img-hd src="/img/influxdb/version-tools-grafana-flux.png" alt="Use Grafana with InfluxDB and Flux" />}}
|
||||
{{% /show-in %}}
|
||||
Click **Save & Test**. Grafana attempts to connect to {{% show-in "v2" %}}InfluxDB OSS 2.x{{% /show-in %}}{{% show-in "cloud" %}}InfluxDB Cloud{{% /show-in %}} and returns the results of the test.
|
||||
|
||||
<!---------------------------------- END FLUX ---------------------------------->
|
||||
{{% /tab-content %}}
|
||||
<!----------------------------- END FLUX CONTENT ----------------------------->
|
||||
<!-------------------------- BEGIN INFLUXQL CONTENT -------------------------->
|
||||
{{% tab-content %}}
|
||||
<!------------------------------- BEGIN INFLUXQL ------------------------------>
|
||||
|
||||
## Configure Grafana to use InfluxQL
|
||||
|
||||
<!---------------------------------------------------------------------------->
|
||||
<!------------------------- BEGIN OSS InfluxQL setup ------------------------->
|
||||
<!---------------------------------------------------------------------------->
|
||||
{{% show-in "v2" %}}
|
||||
> [!Important]
|
||||
> #### DBRP mapping required
|
||||
>
|
||||
> To query InfluxDB OSS 2.x with InfluxQL, you must first create Database and Retention Policy (DBRP) mappings.
|
||||
> The configuration form displays a warning if DBRP mapping is required.
|
||||
|
||||
To query InfluxDB {{< current-version >}} with InfluxQL, find your use case below,
|
||||
and then complete the instructions to configure Grafana:
|
||||
When you select **InfluxQL** as the query language, you can authenticate using either tokens or username/password credentials.
|
||||
|
||||
- [Installed a new InfluxDB {{< current-version >}} instance](#installed-a-new-influxdb-instance)
|
||||
- [Upgraded from InfluxDB 1.x to {{< current-version >}} (following the official upgrade)](#upgraded-from-influxdb-1x-to-2x)
|
||||
- [Manually migrated from InfluxDB 1.x to {{< current-version >}}](#manually-migrated-from-influxdb-1x-to-2x)
|
||||
### Token authentication (recommended)
|
||||
|
||||
### Installed a new InfluxDB instance
|
||||
Configure the following fields:
|
||||
|
||||
To configure Grafana to use InfluxQL with a new install of InfluxDB {{< current-version >}}, do the following:
|
||||
- **Database**: The database name [mapped to your InfluxDB bucket](#create-dbrp-mappings)
|
||||
- **User**: Enter any string (this field is required by the form)
|
||||
- **Password**: Your InfluxDB [API token](/influxdb/v2/admin/tokens/)
|
||||
|
||||
1. [Authenticate with InfluxDB {{< current-version >}} tokens](/influxdb/version/admin/tokens/).
|
||||
2. [Manually create DBRP mappings](#view-and-create-influxdb-dbrp-mappings).
|
||||
### Username and password authentication
|
||||
|
||||
### Upgraded from InfluxDB 1.x to 2.x
|
||||
Configure the following fields:
|
||||
|
||||
To configure Grafana to use InfluxQL when you've upgraded from InfluxDB 1.x to
|
||||
InfluxDB {{< current-version >}} (following an [official upgrade guide](/influxdb/version/upgrade/v1-to-v2/)):
|
||||
- **Database**: The database name [mapped to your InfluxDB bucket](#create-dbrp-mappings)
|
||||
- **User**: Your [v1 authorization username](#create-v1-authorizations)
|
||||
- **Password**: Your [v1 authorization password](#create-v1-authorizations)
|
||||
|
||||
1. Authenticate using the _non-admin_ [v1 compatible authentication credentials](#view-and-create-influxdb-v1-authorizations)
|
||||
created during the upgrade process.
|
||||
2. Use the DBRP mappings InfluxDB automatically created in the upgrade process (no action necessary).
|
||||
{{% show-in "v2" %}}{{< img-hd src="/img/influxdb/OSS-v2-grafana-product-dropdown-influxql.png" alt="InfluxQL configuration for InfluxDB OSS 2.x with DBRP warning" />}}{{% /show-in %}}
|
||||
{{% show-in "cloud" %}}{{< img-hd src="/img/influxdb/influxdb-v2-cloud-influxql.png" alt="InfluxQL configuration for InfluxDB Cloud (TSM) with v1 auth" />}}{{% /show-in %}}
|
||||
|
||||
### Manually migrated from InfluxDB 1.x to 2.x
|
||||
Click **Save & Test**. Grafana attempts to connect to {{% show-in "v2" %}}InfluxDB OSS 2.x{{% /show-in %}}{{% show-in "cloud" %}}InfluxDB Cloud{{% /show-in %}} and returns the results of the test.
|
||||
|
||||
To configure Grafana to use InfluxQL when you've manually migrated from InfluxDB
|
||||
1.x to InfluxDB {{< current-version >}}, do the following:
|
||||
### Create DBRP mappings
|
||||
|
||||
1. If your InfluxDB 1.x instance required authentication,
|
||||
[create v1 compatible authentication credentials](#view-and-create-influxdb-v1-authorizations)
|
||||
to match your previous 1.x username and password.
|
||||
Otherwise, use [InfluxDB v2 token authentication](/influxdb/version/admin/tokens/).
|
||||
2. [Manually create DBRP mappings](#view-and-create-influxdb-dbrp-mappings).
|
||||
When using InfluxQL to query InfluxDB, the query must specify a database and retention policy.
|
||||
InfluxDB DBRP mappings associate database and retention policy combinations with InfluxDB OSS 2.x buckets.
|
||||
|
||||
{{< expand-wrapper >}}
|
||||
{{% expand "View and create InfluxDB v1 authorizations" %}}
|
||||
#### View existing DBRP mappings
|
||||
|
||||
InfluxDB {{< current-version >}} provides a 1.x compatible authentication API that lets you
|
||||
authenticate with a username and password like InfluxDB 1.x
|
||||
_(separate from the credentials used to log into the InfluxDB user interface)_.
|
||||
Use the [`influx v1 dbrp list`](/influxdb/v2/reference/cli/influx/v1/dbrp/list/) command:
|
||||
```sh
|
||||
influx v1 dbrp list
|
||||
```
|
||||
|
||||
### Create a DBRP mappings
|
||||
|
||||
Use the influx v1 dbrp create command:
|
||||
```sh
|
||||
influx v1 dbrp create \
|
||||
--db example-db \
|
||||
--rp example-rp \
|
||||
--bucket-id 00xX00o0X001 \
|
||||
--default
|
||||
```
|
||||
|
||||
Provide:
|
||||
|
||||
- `--db:` Database name
|
||||
- `--rp:` Retention policy name (not retention period)
|
||||
- `--bucket-id:` Bucket ID
|
||||
- `--default:` (Optional) Make this the default retention policy for the database
|
||||
|
||||
> [!Note]
|
||||
> **Repeat for each DBRP combination**
|
||||
> Each unique database and retention policy combination used by Grafana must be mapped to an InfluxDB OSS 2.x bucket.
|
||||
|
||||
For more information, see [Database and retention policy mapping](/influxdb/v2/api-guide/influxdb-1x/dbrp/).
|
||||
|
||||
### Create v1 authorizations
|
||||
|
||||
InfluxDB OSS 2.x provides a v1-compatible authentication API for username/password authentication.
|
||||
|
||||
#### View existing v1 authorizations
|
||||
|
||||
Use the [`influx v1 auth list`](/influxdb/version/reference/cli/influx/v1/auth/list/)
|
||||
to list existing InfluxDB v1 compatible authorizations.
|
||||
|
||||
Use the [`influx v1 auth list`](/influxdb/v2/reference/cli/influx/v1/auth/list/) command:
|
||||
```sh
|
||||
influx v1 auth list
|
||||
```
|
||||
|
||||
#### Create a v1 authorization
|
||||
|
||||
Use the [`influx v1 auth create` command](/influxdb/version/reference/cli/influx/v1/auth/create/)
|
||||
to grant read/write permissions to specific buckets. Provide the following:
|
||||
|
||||
- [bucket IDs](/influxdb/version/admin/buckets/view-buckets/) to grant read
|
||||
or write permissions to
|
||||
- new username
|
||||
- new password _(when prompted)_
|
||||
|
||||
<!-- -->
|
||||
Use the [`influx v1 auth create`](/influxdb/v2/reference/cli/influx/v1/auth/create/) command:
|
||||
```sh
|
||||
influx v1 auth create \
|
||||
--read-bucket 00xX00o0X001 \
|
||||
--write-bucket 00xX00o0X001 \
|
||||
--username example-user
|
||||
```
|
||||
{{% /expand %}}
|
||||
{{< expand "View and create InfluxDB DBRP mappings" >}}
|
||||
|
||||
When using InfluxQL to query InfluxDB, the query must specify a database and a retention policy.
|
||||
InfluxDB DBRP mappings associate database and retention policy combinations with
|
||||
InfluxDB {{< current-version >}} [buckets](/influxdb/version/reference/glossary/#bucket).
|
||||
Provide:
|
||||
|
||||
DBRP mappings do not affect the retention period of the target bucket.
|
||||
These mappings allow queries following InfluxDB 1.x conventions to successfully
|
||||
query InfluxDB {{< current-version >}} buckets.
|
||||
- `--read-bucket`: Bucket ID to grant read permissions
|
||||
- `--write-bucket`: Bucket ID to grant write permissions
|
||||
- `--username`: New username
|
||||
|
||||
#### View existing DBRP mappings
|
||||
|
||||
Use the [`influx v1 dbrp list`](/influxdb/version/reference/cli/influx/v1/dbrp/list/)
|
||||
to list existing DBRP mappings.
|
||||
|
||||
```sh
|
||||
influx v1 dbrp list
|
||||
```
|
||||
|
||||
#### Create a DBRP mapping
|
||||
|
||||
Use the [`influx v1 dbrp create` command](/influxdb/version/reference/cli/influx/v1/dbrp/create/)
|
||||
command to create a DBRP mapping.
|
||||
Provide the following:
|
||||
|
||||
- database name
|
||||
- retention policy name _(not retention period)_
|
||||
- [bucket ID](/influxdb/version/admin/buckets/view-buckets/)
|
||||
- _(optional)_ `--default` flag if you want the retention policy to be the default retention
|
||||
policy for the specified database
|
||||
|
||||
```sh
|
||||
influx v1 dbrp create \
|
||||
--db example-db \
|
||||
--rp example-rp \
|
||||
--bucket-id 00xX00o0X001 \
|
||||
--default
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
#### Repeat for each DBRP combination
|
||||
|
||||
Each unique database and retention policy combination used by Grafana must be
|
||||
mapped to an InfluxDB {{< current-version >}} bucket.
|
||||
If you have multiple retention policies for a single bucket, set one of the the
|
||||
retention polices as the default using the `--default` flag.
|
||||
{{% /note %}}
|
||||
|
||||
_For more information about DBRP mapping, see
|
||||
[Database and retention policy mapping](/influxdb/version/reference/api/influxdb-1x/dbrp/)._
|
||||
|
||||
{{< /expand >}}
|
||||
{{< /expand-wrapper >}}
|
||||
|
||||
{{% /show-in %}}
|
||||
<!---------------------------------------------------------------------------->
|
||||
<!-------------------------- END OSS InfluxQL setup -------------------------->
|
||||
<!---------------------------------------------------------------------------->
|
||||
|
||||
<!---------------------------------------------------------------------------->
|
||||
<!------------------------ BEGIN Cloud InfluxQL setup ------------------------>
|
||||
<!---------------------------------------------------------------------------->
|
||||
{{% show-in "cloud,cloud-serverless" %}}
|
||||
|
||||
To query InfluxDB Cloud from Grafana using InfluxQL:
|
||||
|
||||
1. [Download and set up the `influx` CLI](#download-and-set-up-the-influx-cli)
|
||||
2. [Create an InfluxDB DBRP mapping](#create-an-influxdb-dbrp-mapping)
|
||||
3. [Configure your InfluxDB connection](#configure-your-influxdb-connection)
|
||||
|
||||
### Download and set up the influx CLI
|
||||
|
||||
1. [Download the latest version of the `influx` CLI](/influxdb/cloud/sign-up/#optional-download-install-and-use-the-influx-cli)
|
||||
appropriate for your local operating system.
|
||||
2. Create a CLI configuration that provides the required InfluxDB Cloud **host**,
|
||||
**organization**, and **API token** to all CLI commands.
|
||||
Use the [`influx config create` command](/influxdb/cloud/reference/cli/influx/config/create/)
|
||||
and provide the following:
|
||||
|
||||
- [InfluxDB Cloud URL](/influxdb/cloud/reference/regions/)
|
||||
- [organization name](/influxdb/cloud/admin/organizations/) _(by default, your email address)_
|
||||
- [API token](/influxdb/cloud/admin/tokens/)
|
||||
|
||||
```sh
|
||||
influx config create \
|
||||
--config-name example-config-name \
|
||||
--host-url https://{{< influxdb/host >}} \
|
||||
--org example-org \
|
||||
--token My5uP3rSeCr37t0k3n
|
||||
```
|
||||
|
||||
For more information about `influx` CLI configurations,
|
||||
see [`influx config`](/influxdb/cloud/reference/cli/influx/config/).
|
||||
|
||||
### Create an InfluxDB DBRP mapping
|
||||
|
||||
When using InfluxQL to query InfluxDB Cloud, the query must specify a database and a retention policy.
|
||||
Use the [`influx v1 dbrp create` command](/influxdb/cloud/reference/cli/influx/v1/dbrp/create/)
|
||||
command to create a database/retention policy (DBRP) mapping that associates a database
|
||||
and retention policy combination with an InfluxDB Cloud [bucket](/influxdb/cloud/reference/glossary/#bucket).
|
||||
|
||||
DBRP mappings do not affect the retention period of the target bucket.
|
||||
These mappings allow queries following InfluxDB 1.x conventions to successfully
|
||||
query InfluxDB Cloud buckets.
|
||||
|
||||
{{% note %}}
|
||||
##### Automatically create DBRP mappings on write
|
||||
|
||||
When using the InfluxDB 1.x compatibility API to write data to InfluxDB Cloud,
|
||||
InfluxDB Cloud automatically creates DBRP mappings for buckets whose names match the
|
||||
`db/rp` naming pattern of the database and retention policy specified in the write request.
|
||||
For more information, see [Database and retention policy mapping – Writing data](/influxdb/cloud/reference/api/influxdb-1x/dbrp/#when-writing-data).
|
||||
{{% /note %}}
|
||||
|
||||
Provide the following:
|
||||
|
||||
- database name
|
||||
- [retention policy](/influxdb/v1/concepts/glossary/#retention-policy-rp) name _(not retention period)_
|
||||
- [bucket ID](/influxdb/cloud/admin/buckets/view-buckets/)
|
||||
- _(optional)_ `--default` flag if you want the retention policy to be the default retention
|
||||
policy for the specified database
|
||||
|
||||
```sh
|
||||
influx v1 dbrp create \
|
||||
--db example-db \
|
||||
--rp example-rp \
|
||||
--bucket-id 00xX00o0X001 \
|
||||
--default
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
#### Repeat for each DBRP combination
|
||||
|
||||
Each unique database and retention policy combination used by Grafana must be
|
||||
mapped to an InfluxDB {{< current-version >}} bucket.
|
||||
If you have multiple retention policies for a single bucket, set one of the the
|
||||
retention polices as the default using the `--default` flag.
|
||||
{{% /note %}}
|
||||
|
||||
_For more information about DBRP mapping, see
|
||||
[Database and retention policy mapping](/influxdb/cloud/reference/api/influxdb-1x/dbrp/)._
|
||||
|
||||
{{% /show-in %}}
|
||||
<!---------------------------------------------------------------------------->
|
||||
<!------------------------- END Cloud InfluxQL setup ------------------------->
|
||||
<!---------------------------------------------------------------------------->
|
||||
|
||||
|
||||
### Configure your InfluxDB connection
|
||||
|
||||
With **InfluxQL** selected as the query language in your InfluxDB data source settings:
|
||||
|
||||
1. Under **HTTP**, enter the following:
|
||||
|
||||
- **URL**: Your [InfluxDB URL](/influxdb/version/reference/urls/).
|
||||
|
||||
```sh
|
||||
http://localhost:8086/
|
||||
```
|
||||
|
||||
2. Configure InfluxDB authentication:
|
||||
|
||||
- ##### Token authentication
|
||||
|
||||
- Under **Custom HTTP Headers**, select **{{< icon "plus" >}}Add Header**. Provide your InfluxDB API token:
|
||||
|
||||
- **Header**: Enter `Authorization`
|
||||
- **Value**: Use the `Token` schema and provide your [InfluxDB API token](/influxdb/version/admin/tokens/).
|
||||
For example:
|
||||
|
||||
```
|
||||
Token y0uR5uP3rSecr3tT0k3n
|
||||
```
|
||||
|
||||
- Under **InfluxDB Details**, do the following:
|
||||
|
||||
- **Database**: Enter the database name [mapped to your InfluxDB {{< current-version >}} bucket](#view-and-create-influxdb-dbrp-mappings)
|
||||
- **HTTP Method**: Select **GET**
|
||||
|
||||
- ##### Authenticate with username and password
|
||||
|
||||
Under **InfluxDB Details**, do the following:
|
||||
|
||||
- **Database**: Enter the database name [mapped to your InfluxDB {{< current-version >}} bucket](#view-and-create-influxdb-dbrp-mappings)
|
||||
- **User**: Enter the username associated with your [InfluxDB 1.x compatibility authorization](#view-and-create-influxdb-v1-authorizations)
|
||||
- **Password**: Enter the password associated with your [InfluxDB 1.x compatibility authorization](#view-and-create-influxdb-dbrp-mappings)
|
||||
- **HTTP Method**: Select **GET**
|
||||
|
||||
3. Click **Save & Test**. Grafana attempts to connect to the InfluxDB {{< current-version >}} data source
|
||||
and returns the results of the test.
|
||||
|
||||
{{% show-in "cloud,cloud-serverless" %}}
|
||||
{{< img-hd src="/img/influxdb/cloud-tools-grafana-influxql.png" alt="Use Grafana with InfluxDB Cloud and Flux" />}}
|
||||
{{% /show-in %}}
|
||||
|
||||
{{< show-in "v2" >}}
|
||||
{{< img-hd src="/img/influxdb/version-tools-grafana-influxql.png" alt="Use Grafana with InfluxDB and Flux" />}}
|
||||
{{< /show-in >}}
|
||||
You'll be prompted to enter a password.
|
||||
<!-------------------------------- END INFLUXQL ------------------------------->
|
||||
|
||||
{{% /tab-content %}}
|
||||
<!--------------------------- END INFLUXQL CONTENT --------------------------->
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
## Query and visualize data
|
||||
|
||||
With your InfluxDB connection configured, use Grafana and Flux to query and
|
||||
visualize time series data stored in your **InfluxDB** instance.
|
||||
With your InfluxDB connection configured, use Grafana to query and visualize time series data.
|
||||
|
||||
For more information about using Grafana, see the [Grafana documentation](https://grafana.com/docs/).
|
||||
If you're just learning Flux, see [Get started with Flux](/flux/v0/get-started/).
|
||||
### Query inspection in Grafana
|
||||
|
||||
To learn about query management and inspection in Grafana, see the
|
||||
[Grafana Explore documentation](https://grafana.com/docs/grafana/latest/explore/).
|
||||
|
||||
### Build visualizations with Grafana
|
||||
|
||||
For a comprehensive walk-through of creating visualizations with
|
||||
Grafana, see the [Grafana documentation](https://grafana.com/docs/grafana/latest/).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,533 @@
|
|||
Use the Arrow Flight SQL ODBC driver to execute SQL queries against
|
||||
{{% product-name %}} from ODBC-compatible applications and programming languages.
|
||||
|
||||
ODBC (Open Database Connectivity) is a standard API for accessing database
|
||||
management systems. The Arrow Flight SQL ODBC driver enables ODBC-compatible
|
||||
applications to connect to {{% product-name %}} and query data using SQL.
|
||||
|
||||
- [Download and install the ODBC driver](#download-and-install-the-odbc-driver)
|
||||
- [Configure a data source](#configure-a-data-source)
|
||||
- [Connect and query from applications](#connect-and-query-from-applications)
|
||||
- [Use ODBC with programming languages](#use-odbc-with-programming-languages)
|
||||
|
||||
## Download and install the ODBC driver
|
||||
|
||||
{{% product-name %}} uses the Arrow Flight SQL ODBC driver to enable ODBC connectivity.
|
||||
|
||||
> [!Note]
|
||||
> For more information about the Arrow Flight SQL ODBC Driver, see the [Dremio documentation](https://docs.dremio.com/current/client-applications/drivers/arrow-flight-sql-odbc-driver/).
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
[Windows (PowerShell)](#)
|
||||
[Windows (Manual)](#)
|
||||
[macOS and Linux](#)
|
||||
{{% /tabs %}}
|
||||
|
||||
{{% tab-content %}}
|
||||
Run the following PowerShell commands to download and install:
|
||||
|
||||
{{% code-placeholders "YOUR_USER" %}}
|
||||
```powershell
|
||||
# Set the driver path
|
||||
$driverPath = "C:\Users\YOUR_USER\Downloads\arrow-flight-sql-odbc-0.9.7.1195-win64.msi"
|
||||
|
||||
# Download the driver
|
||||
Invoke-WebRequest -Uri "https://docs.influxdata.com/downloads/arrow-flight-sql-odbc-0.9.7.1195-win64.msi" `
|
||||
-OutFile $driverPath
|
||||
|
||||
# Mark as trusted
|
||||
Unblock-File $driverPath
|
||||
|
||||
# Install
|
||||
Start-Process msiexec.exe -Wait -ArgumentList "/i `"$driverPath`""
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
|
||||
Replace the following:
|
||||
|
||||
- {{% code-placeholder-key %}}`YOUR_USER`{{% /code-placeholder-key %}}: Your Windows username
|
||||
|
||||
#### Verify installation
|
||||
|
||||
1. Open **ODBC Data Source Administrator (64-bit)**
|
||||
2. Navigate to the **Drivers** tab
|
||||
3. Verify **Arrow Flight SQL ODBC Driver** appears in the list
|
||||
|
||||
{{% /tab-content %}}
|
||||
|
||||
{{% tab-content %}}
|
||||
<a class="btn" href="https://docs.influxdata.com/downloads/arrow-flight-sql-odbc-0.9.7.1195-win64.msi">Download the Arrow Flight SQL ODBC driver</a>
|
||||
|
||||
1. Run the downloaded `.msi` installer
|
||||
2. Follow the installation wizard using default settings
|
||||
3. Complete the installation
|
||||
|
||||
#### Verify installation
|
||||
|
||||
1. Open **ODBC Data Source Administrator (64-bit)**
|
||||
2. Navigate to the **Drivers** tab
|
||||
3. Verify **Arrow Flight SQL ODBC Driver** appears in the list
|
||||
|
||||
{{% /tab-content %}}
|
||||
|
||||
{{% tab-content %}}
|
||||
Download from Dremio:
|
||||
|
||||
- [**macOS (Universal)**](https://download.dremio.com/arrow-flight-sql-odbc-driver/arrow-flight-sql-odbc-LATEST-universal.pkg)
|
||||
- [**Linux (x86_64)**](https://download.dremio.com/arrow-flight-sql-odbc-driver/arrow-flight-sql-odbc-LATEST-linux-x86_64.tar.gz)
|
||||
|
||||
#### Install on macOS
|
||||
|
||||
1. Run the downloaded `.pkg` installer
|
||||
2. Follow the installation prompts
|
||||
3. Enter your administrator password when prompted
|
||||
4. Complete the installation
|
||||
|
||||
#### Install on Linux
|
||||
|
||||
1. Extract the downloaded archive:
|
||||
|
||||
```bash
|
||||
tar -xzf arrow-flight-sql-odbc-LATEST-linux-x86_64.tar.gz
|
||||
```
|
||||
|
||||
2. Install the driver (installation location may vary by distribution):
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /opt/arrow-flight-sql-odbc
|
||||
sudo cp -r lib /opt/arrow-flight-sql-odbc/
|
||||
```
|
||||
|
||||
3. Configure the driver in `/etc/odbcinst.ini`:
|
||||
|
||||
```ini
|
||||
[Arrow Flight SQL ODBC Driver]
|
||||
Description = Arrow Flight SQL ODBC Driver
|
||||
Driver = /opt/arrow-flight-sql-odbc/lib/libarrow-odbc.so
|
||||
```
|
||||
|
||||
#### Verify installation
|
||||
|
||||
To verify the driver is installed correctly, run:
|
||||
|
||||
```bash
|
||||
odbcinst -q -d
|
||||
```
|
||||
|
||||
The output should include **Arrow Flight SQL**.
|
||||
|
||||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
## Configure a data source
|
||||
|
||||
After installing the Arrow Flight SQL ODBC driver, configure a data source to
|
||||
connect to {{% product-name %}}.
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
[Windows](#)
|
||||
[macOS and Linux](#)
|
||||
{{% /tabs %}}
|
||||
|
||||
{{% tab-content %}}
|
||||
1. Open **ODBC Data Source Administrator (64-bit)**
|
||||
2. Navigate to the **System DSN** or **User DSN** tab
|
||||
3. Click **Add**
|
||||
4. Select **Arrow Flight SQL ODBC Driver** and click **Finish**
|
||||
5. Configure the connection:
|
||||
|
||||
- **Data Source Name**: Provide a descriptive name (for example, `InfluxDB3`)
|
||||
- **Host**: Your {{% product-name %}} host (for example, {{% show-in "cloud-serverless" %}}`us-west-2-1.aws.cloud2.influxdata.com`{{% /show-in %}}{{% show-in "enterprise,core" %}}`localhost`{{% /show-in %}}{{% show-in "cloud-dedicated" %}}`cluster-id.a.influxdb.io`{{% /show-in %}}{{% show-in "clustered" %}}`cluster-host.com`{{% /show-in %}})
|
||||
- **Port**: Your InfluxDB URL port {{% show-in "cloud-serverless,cloud-dedicated,clustered" %}}(for example, `443` (HTTPS){{% /show-in %}}{{% show-in "enterprise,core" %}}`8181` (default){{% /show-in %}})
|
||||
- **Database**: Your database name
|
||||
- **Auth Token**: Your {{% show-in "cloud-dedicated,clustered" %}}{{% token-link "database" %}}{{% /show-in %}}{{% show-in "cloud-serverless" %}}{{% token-link %}}{{% /show-in %}}{{% show-in "core,enterprise" %}}{{% token-link "admin" "database" %}}{{% /show-in %}}{{% show-in "cloud-dedicated,clustered,enterprise" %}} with query permissions for the target database{{% /show-in %}}
|
||||
- **Use Encryption**: Enable for HTTPS connections
|
||||
|
||||
6. Click **Test** to verify the connection
|
||||
7. Click **OK** to save
|
||||
|
||||
{{% /tab-content %}}
|
||||
|
||||
{{% tab-content %}}
|
||||
Create or edit `~/.odbc.ini` (user DSN) or `/etc/odbc.ini` (system DSN):
|
||||
|
||||
{{% show-in "enterprise,core" %}}
|
||||
{{% code-placeholders "DATABASE_NAME|DATABASE_TOKEN" %}}
|
||||
```ini
|
||||
[InfluxDB3]
|
||||
Driver = Arrow Flight SQL ODBC Driver
|
||||
Host = localhost
|
||||
Port = 8181
|
||||
Database = DATABASE_NAME
|
||||
AuthToken = DATABASE_TOKEN
|
||||
UseEncryption = 1
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
{{% /show-in %}}
|
||||
|
||||
{{% show-in "cloud-serverless" %}}
|
||||
{{% code-placeholders "DATABASE_NAME|DATABASE_TOKEN" %}}
|
||||
```ini
|
||||
[InfluxDB3]
|
||||
Driver = Arrow Flight SQL ODBC Driver
|
||||
Host = us-west-2-1.aws.cloud2.influxdata.com
|
||||
Port = 443
|
||||
Database = DATABASE_NAME
|
||||
AuthToken = DATABASE_TOKEN
|
||||
UseEncryption = 1
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
{{% /show-in %}}
|
||||
|
||||
{{% show-in "cloud-dedicated" %}}
|
||||
{{% code-placeholders "DATABASE_NAME|DATABASE_TOKEN" %}}
|
||||
```ini
|
||||
[InfluxDB3]
|
||||
Driver = Arrow Flight SQL ODBC Driver
|
||||
Host = cluster-id.a.influxdb.io
|
||||
Port = 443
|
||||
Database = DATABASE_NAME
|
||||
AuthToken = DATABASE_TOKEN
|
||||
UseEncryption = 1
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
{{% /show-in %}}
|
||||
|
||||
{{% show-in "clustered" %}}
|
||||
{{% code-placeholders "DATABASE_NAME|DATABASE_TOKEN" %}}
|
||||
```ini
|
||||
[InfluxDB3]
|
||||
Driver = Arrow Flight SQL ODBC Driver
|
||||
Host = cluster-host.com
|
||||
Port = 443
|
||||
Database = DATABASE_NAME
|
||||
AuthToken = DATABASE_TOKEN
|
||||
UseEncryption = 1
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
{{% /show-in %}}
|
||||
|
||||
Replace the following:
|
||||
|
||||
- {{% code-placeholder-key %}}`DATABASE_NAME`{{% /code-placeholder-key %}}: Your database name
|
||||
- {{% code-placeholder-key %}}`DATABASE_TOKEN`{{% /code-placeholder-key %}}: Your {{% token-link "database" %}}{{% show-in "enterprise" %}} with query permissions{{% /show-in %}}
|
||||
|
||||
Test the connection:
|
||||
|
||||
```bash
|
||||
isql -v InfluxDB3
|
||||
```
|
||||
|
||||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
## Connect and query from applications
|
||||
|
||||
After configuring a data source, connect from ODBC-compatible applications:
|
||||
|
||||
### Power BI
|
||||
|
||||
See [Use Power BI to visualize data](/influxdb3/version/visualize-data/powerbi/).
|
||||
|
||||
### Tableau
|
||||
|
||||
See [Use Tableau to visualize data](/influxdb3/version/visualize-data/tableau/).
|
||||
|
||||
### Excel
|
||||
|
||||
1. Open Excel
|
||||
2. Go to **Data** > **Get Data** > **From Other Sources** > **From ODBC**
|
||||
3. Select your InfluxDB data source
|
||||
4. Enter credentials if prompted
|
||||
5. Select tables and load data
|
||||
|
||||
### DBeaver
|
||||
|
||||
1. Create a new database connection
|
||||
2. Select **ODBC** as the connection type
|
||||
3. Configure the connection:
|
||||
- **Database/Schema**: Your InfluxDB database
|
||||
- **ODBC DSN**: Your configured data source name
|
||||
4. Test and save the connection
|
||||
|
||||
## Use ODBC with programming languages
|
||||
|
||||
### Python with pyodbc
|
||||
|
||||
```python
|
||||
import pyodbc
|
||||
|
||||
# Connect to InfluxDB
|
||||
conn = pyodbc.connect(
|
||||
'DSN=InfluxDB3',
|
||||
autocommit=True
|
||||
)
|
||||
|
||||
# Create cursor
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Execute query
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
time,
|
||||
temp,
|
||||
location
|
||||
FROM
|
||||
home
|
||||
WHERE
|
||||
time >= now() - INTERVAL '1 hour'
|
||||
ORDER BY
|
||||
time DESC
|
||||
""")
|
||||
|
||||
# Fetch results
|
||||
for row in cursor.fetchall():
|
||||
print(row)
|
||||
|
||||
# Close connection
|
||||
cursor.close()
|
||||
conn.close()
|
||||
```
|
||||
|
||||
### R with RODBC
|
||||
|
||||
```r
|
||||
library(RODBC)
|
||||
|
||||
# Connect to InfluxDB
|
||||
conn <- odbcConnect("InfluxDB3")
|
||||
|
||||
# Execute query
|
||||
result <- sqlQuery(conn, "
|
||||
SELECT
|
||||
time,
|
||||
temp,
|
||||
location
|
||||
FROM
|
||||
home
|
||||
WHERE
|
||||
time >= now() - INTERVAL '1 hour'
|
||||
ORDER BY
|
||||
time DESC
|
||||
")
|
||||
|
||||
# View results
|
||||
print(result)
|
||||
|
||||
# Close connection
|
||||
odbcClose(conn)
|
||||
```
|
||||
|
||||
### C# with `System.Data.Odbc`
|
||||
|
||||
```csharp
|
||||
using System;
|
||||
using System.Data.Odbc;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
string connectionString = "DSN=InfluxDB3";
|
||||
|
||||
using (OdbcConnection conn = new OdbcConnection(connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
string query = @"
|
||||
SELECT
|
||||
time,
|
||||
temp,
|
||||
location
|
||||
FROM
|
||||
home
|
||||
WHERE
|
||||
time >= now() - INTERVAL '1 hour'
|
||||
ORDER BY
|
||||
time DESC
|
||||
";
|
||||
|
||||
using (OdbcCommand cmd = new OdbcCommand(query, conn))
|
||||
using (OdbcDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Console.WriteLine($"{reader["time"]} - {reader["temp"]} - {reader["location"]}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Connection string format
|
||||
|
||||
For applications that use connection strings directly:
|
||||
|
||||
```
|
||||
Driver={Arrow Flight SQL ODBC Driver};Host=HOST;Port=PORT;Database=DATABASE;AuthToken=TOKEN;UseEncryption=1
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
{{% code-placeholders "DATABASE_NAME|DATABASE_TOKEN" %}}
|
||||
```
|
||||
Driver={Arrow Flight SQL ODBC Driver};Host=localhost;Port=8181;Database=DATABASE_NAME;AuthToken=DATABASE_TOKEN;UseEncryption=1
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
|
||||
{{% show-in "cloud-serverless,cloud-dedicated" %}}
|
||||
For {{% product-name %}}, use port `443`:
|
||||
|
||||
{{% code-placeholders "DATABASE_NAME|DATABASE_TOKEN" %}}
|
||||
```
|
||||
Driver={Arrow Flight SQL ODBC Driver};Host=cluster-id.a.influxdb.io;Port=443;Database=DATABASE_NAME;AuthToken=DATABASE_TOKEN;UseEncryption=1
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
{{% /show-in %}}
|
||||
|
||||
## Configuration options
|
||||
|
||||
### Connection parameters
|
||||
|
||||
| Parameter | Description | Default |
|
||||
| -------------------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `Host` | InfluxDB server hostname | Required |
|
||||
| `Port` | InfluxDB server port | Required {{% show-in "core,enterprise" %}}(`8181`){{% /show-in %}} |
|
||||
| `Database` | Database name | Required |
|
||||
| `AuthToken` | Authentication token | Required |
|
||||
| `UseEncryption` | Use encrypted connection | `1` (enabled) |
|
||||
| `TrustedCerts` | Path to trusted CA certificates | System default |
|
||||
| `DisableCertificateVerification` | Skip certificate verification | `0` (disabled) |
|
||||
|
||||
### Advanced options
|
||||
|
||||
Add these to your DSN configuration or connection string as needed:
|
||||
|
||||
{{% show-in "enterprise,core" %}}
|
||||
```ini
|
||||
[InfluxDB3]
|
||||
Driver = Arrow Flight SQL ODBC Driver
|
||||
Host = localhost
|
||||
Port = 8181
|
||||
Database = mydb
|
||||
AuthToken = your-token
|
||||
UseEncryption = 1
|
||||
DisableCertificateVerification = 0
|
||||
```
|
||||
{{% /show-in %}}
|
||||
|
||||
{{% show-in "cloud-serverless" %}}
|
||||
```ini
|
||||
[InfluxDB3]
|
||||
Driver = Arrow Flight SQL ODBC Driver
|
||||
Host = us-west-2-1.aws.cloud2.influxdata.com
|
||||
Port = 443
|
||||
Database = mydb
|
||||
AuthToken = your-token
|
||||
UseEncryption = 1
|
||||
DisableCertificateVerification = 0
|
||||
```
|
||||
{{% /show-in %}}
|
||||
|
||||
{{% show-in "cloud-dedicated" %}}
|
||||
```ini
|
||||
[InfluxDB3]
|
||||
Driver = Arrow Flight SQL ODBC Driver
|
||||
Host = cluster-id.a.influxdb.io
|
||||
Port = 443
|
||||
Database = mydb
|
||||
AuthToken = your-token
|
||||
UseEncryption = 1
|
||||
DisableCertificateVerification = 0
|
||||
```
|
||||
{{% /show-in %}}
|
||||
|
||||
{{% show-in "clustered" %}}
|
||||
```ini
|
||||
[InfluxDB3]
|
||||
Driver = Arrow Flight SQL ODBC Driver
|
||||
Host = cluster-host.com
|
||||
Port = 443
|
||||
Database = mydb
|
||||
AuthToken = your-token
|
||||
UseEncryption = 1
|
||||
DisableCertificateVerification = 0
|
||||
```
|
||||
{{% /show-in %}}
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Driver not found
|
||||
|
||||
If applications cannot find the Arrow Flight SQL ODBC driver:
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
[Windows](#)
|
||||
[macOS and Linux](#)
|
||||
{{% /tabs %}}
|
||||
|
||||
{{% tab-content %}}
|
||||
1. Open **ODBC Data Source Administrator (64-bit)**
|
||||
2. Navigate to the **Drivers** tab
|
||||
3. Verify **Arrow Flight SQL ODBC Driver** appears in the list
|
||||
4. If not listed, reinstall the driver
|
||||
|
||||
{{% /tab-content %}}
|
||||
|
||||
{{% tab-content %}}
|
||||
1. Run the following command to list installed drivers:
|
||||
|
||||
```bash
|
||||
odbcinst -q -d
|
||||
```
|
||||
|
||||
2. Verify **Arrow Flight SQL** appears in the output
|
||||
3. Check `/etc/odbcinst.ini` for proper driver configuration
|
||||
4. Ensure the driver library path is correct
|
||||
|
||||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
### Connection failures
|
||||
|
||||
If you cannot connect to {{% product-name %}}:
|
||||
|
||||
- Verify your {{% product-name %}} instance is running and accessible
|
||||
- Check host and port settings:
|
||||
- Local instances: `localhost:8181`
|
||||
- {{% show-in "cloud-serverless,cloud-dedicated" %}}{{% product-name %}}: Use your cluster URL with port `443`{{% /show-in %}}
|
||||
- Ensure `UseEncryption` is set correctly for your connection type
|
||||
- Verify network connectivity and firewall rules allow connections
|
||||
|
||||
### Authentication errors
|
||||
|
||||
If authentication fails:
|
||||
|
||||
- Confirm your token is valid and not expired
|
||||
- Ensure the token is specified in the `AuthToken` parameter (not `Token`)
|
||||
- {{% show-in "enterprise" %}}Verify the token has query permissions for the target database{{% /show-in %}}
|
||||
- Check that the token was copied correctly without extra spaces or characters
|
||||
|
||||
### Query errors
|
||||
|
||||
If queries fail or return errors:
|
||||
|
||||
- Verify SQL syntax is correct for InfluxDB SQL
|
||||
- Check that referenced tables (measurements) exist in the database
|
||||
- Ensure column names match your schema
|
||||
- Review the [SQL reference](/influxdb3/version/reference/sql/) for supported features
|
||||
- For large result sets, consider adding `LIMIT` clauses
|
||||
|
||||
### Performance issues
|
||||
|
||||
For slow queries or connection timeouts:
|
||||
|
||||
- Add time range filters to limit data scanned
|
||||
- Use appropriate indexes if available
|
||||
- Increase timeout values in your DSN configuration
|
||||
- Monitor query execution plans for optimization opportunities
|
||||
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
Use [Grafana](https://grafana.com/) to query and visualize data from
|
||||
{{% product-name %}}.
|
||||
|
||||
> [Grafana] enables you to query, visualize, alert on, and explore your metrics,
|
||||
> logs, and traces wherever they are stored.
|
||||
> [Grafana] provides you with tools to turn your time-series database (TSDB)
|
||||
> data into insightful graphs and visualizations.
|
||||
>
|
||||
> {{% cite %}}-- [Grafana documentation](https://grafana.com/docs/grafana/latest/introduction/){{% /cite %}}
|
||||
|
||||
- [Install Grafana or login to Grafana Cloud](#install-grafana-or-login-to-grafana-cloud)
|
||||
- [InfluxDB data source](#influxdb-data-source)
|
||||
- [Create an InfluxDB data source](#create-an-influxdb-data-source)
|
||||
- [Query InfluxDB with Grafana](#query-influxdb-with-grafana)
|
||||
- [Build visualizations with Grafana](#build-visualizations-with-grafana)
|
||||
|
||||
## Install Grafana or login to Grafana Cloud
|
||||
|
||||
If using the open source version of **Grafana**, follow the
|
||||
[Grafana installation instructions](https://grafana.com/docs/grafana/latest/setup-grafana/installation/)
|
||||
to install Grafana for your operating system.
|
||||
If using **Grafana Cloud**, login to your Grafana Cloud instance.
|
||||
|
||||
## InfluxDB data source
|
||||
|
||||
The InfluxDB data source plugin is included in the Grafana core distribution.
|
||||
Use the plugin to query and visualize data from {{< product-name >}} with
|
||||
both SQL and InfluxQL.
|
||||
|
||||
> [!Note]
|
||||
> #### Grafana 10.3+
|
||||
>
|
||||
> The instructions below are for **Grafana 10.3+** which introduced the newest
|
||||
> version of the InfluxDB core plugin.
|
||||
> The updated plugin includes **SQL support** for InfluxDB 3-based products such
|
||||
> as {{< product-name >}}.
|
||||
|
||||
## Create an InfluxDB data source
|
||||
|
||||
1. In your Grafana user interface (UI), navigate to **Data Sources**.
|
||||
2. Click **Add new data source**.
|
||||
3. Search for and select the **InfluxDB** plugin.
|
||||
4. Provide a name for your data source.
|
||||
5. Under **Query Language**, select either **SQL** or **InfluxQL**:
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
[SQL](#)
|
||||
[InfluxQL](#)
|
||||
{{% /tabs %}}
|
||||
{{% tab-content %}}
|
||||
<!--------------------------------- BEGIN SQL --------------------------------->
|
||||
|
||||
When creating an InfluxDB data source that uses SQL to query data:
|
||||
|
||||
1. Under **HTTP**:
|
||||
|
||||
- **URL**: Provide your {{% product-name %}} URL:
|
||||
|
||||
```
|
||||
http://{{< influxdb/host >}}
|
||||
```
|
||||
|
||||
> [!Note]
|
||||
> If you are _not_ using HTTPS, enable the **Insecure Connection** option
|
||||
> under **InfluxDB Details**.
|
||||
|
||||
2. Under **InfluxDB Details**:
|
||||
|
||||
- **Database**: Provide a default database name to query.
|
||||
- **Token**: Provide an arbitrary, non-empty string.
|
||||
- **Insecure Connection**: If _not_ using HTTPS, enable this option.
|
||||
|
||||
3. Click **Save & test**.
|
||||
|
||||
{{< img-hd src="/img/influxdb3/influxdb3-grafana-sql.png" alt="Grafana InfluxDB data source for InfluxDB 3 that uses SQL" />}}
|
||||
|
||||
<!---------------------------------- END SQL ---------------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{% tab-content %}}
|
||||
<!------------------------------- BEGIN INFLUXQL ------------------------------>
|
||||
|
||||
When creating an InfluxDB data source that uses InfluxQL to query data:
|
||||
|
||||
1. Under **HTTP**:
|
||||
|
||||
- **URL**: Provide your {{% product-name %}} URL:
|
||||
|
||||
```
|
||||
https://{{< influxdb/host >}}
|
||||
```
|
||||
|
||||
2. Under **InfluxDB Details**:
|
||||
|
||||
- **Database**: Provide a default database name to query.
|
||||
- **User**: Provide an arbitrary string.
|
||||
_This credential is ignored when querying {{% product-name %}}, but it cannot be empty._
|
||||
- **Password**: Provide an arbitrary string.
|
||||
- **HTTP Method**: Choose one of the available HTTP request methods to use when querying data:
|
||||
|
||||
- **POST** ({{< req text="Recommended" >}})
|
||||
- **GET**
|
||||
|
||||
3. Click **Save & test**.
|
||||
|
||||
{{< img-hd src="/img/influxdb3/influxdb3-grafana-influxql.png" alt="Grafana InfluxDB data source for InfluxDB 3 that uses InfluxQL" />}}
|
||||
|
||||
<!-------------------------------- END INFLUXQL ------------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
## Query InfluxDB with Grafana
|
||||
|
||||
After you [configure and save an InfluxDB datasource](#create-an-influxdb-data-source),
|
||||
use Grafana to build, run, and inspect queries against {{< product-name >}}.
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
[SQL](#)
|
||||
[InfluxQL](#)
|
||||
{{% /tabs %}}
|
||||
{{% tab-content %}}
|
||||
<!--------------------------------- BEGIN SQL --------------------------------->
|
||||
|
||||
> [!Note]
|
||||
> {{% sql/sql-schema-intro %}}
|
||||
> To learn more, see [Query Data](/influxdb3/version/query-data/sql/).
|
||||
|
||||
1. Click **Explore**.
|
||||
2. In the dropdown, select the saved InfluxDB data source to query.
|
||||
3. Use the SQL query form to build your query:
|
||||
|
||||
- **Table**: Select the measurement to query.
|
||||
- **Column**: Select one or more fields and tags to return as columns in query results.
|
||||
|
||||
With SQL, select the `time` column to include timestamps with the data.
|
||||
Grafana relies on the `time` column to correctly graph time series data.
|
||||
|
||||
- _**Optional:**_ Toggle **filter** to generate **WHERE** clause statements.
|
||||
- **WHERE**: Configure condition expressions to include in the `WHERE` clause.
|
||||
|
||||
- _**Optional:**_ Toggle **group** to generate **GROUP BY** clause statements.
|
||||
|
||||
- **GROUP BY**: Select columns to group by.
|
||||
If you include an aggregation function in the **SELECT** list,
|
||||
you must group by one or more of the queried columns.
|
||||
SQL returns the aggregation for each group.
|
||||
|
||||
- {{< req text="Recommended" color="green" >}}:
|
||||
Toggle **order** to generate **ORDER BY** clause statements.
|
||||
|
||||
- **ORDER BY**: Select columns to sort by.
|
||||
You can sort by time and multiple fields or tags.
|
||||
To sort in descending order, select **DESC**.
|
||||
|
||||
4. {{< req text="Recommended" color="green" >}}: Change format to **Time series**.
|
||||
|
||||
- Use the **Format** dropdown to change the format of the query results.
|
||||
For example, to visualize the query results as a time series, select **Time series**.
|
||||
|
||||
5. Click **Run query** to execute the query.
|
||||
|
||||
<!---------------------------------- END SQL ---------------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{% tab-content %}}
|
||||
<!------------------------------- BEGIN INFLUXQL ------------------------------>
|
||||
|
||||
1. Click **Explore**.
|
||||
2. In the dropdown, select the **InfluxDB** data source that you want to query.
|
||||
3. Use the InfluxQL query form to build your query:
|
||||
|
||||
- **FROM**: Select the measurement that you want to query.
|
||||
- **WHERE**: To filter the query results, enter a conditional expression.
|
||||
- **SELECT**: Select fields to query and an aggregate function to apply to each.
|
||||
The aggregate function is applied to each time interval defined in the
|
||||
`GROUP BY` clause.
|
||||
- **GROUP BY**: By default, Grafana groups data by time to downsample results
|
||||
and improve query performance.
|
||||
You can also add other tags to group by.
|
||||
|
||||
4. Click **Run query** to execute the query.
|
||||
|
||||
<!-------------------------------- END INFLUXQL ------------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
{{< youtube "rSsouoNsNDs" >}}
|
||||
|
||||
To learn about query management and inspection in Grafana, see the
|
||||
[Grafana Explore documentation](https://grafana.com/docs/grafana/latest/explore/).
|
||||
|
||||
## Build visualizations with Grafana
|
||||
|
||||
For a comprehensive walk-through of creating visualizations with
|
||||
Grafana, see the [Grafana documentation](https://grafana.com/docs/grafana/latest/).
|
||||
|
|
@ -0,0 +1,263 @@
|
|||
Use [Microsoft Power BI Desktop](https://powerbi.microsoft.com/) with the
|
||||
InfluxDB 3 custom connector to query and visualize data from {{% product-name %}}.
|
||||
|
||||
Note: The Microsoft Power BI Connector for InfluxDB is currently in BETA
|
||||
|
||||
> Microsoft Power BI is a collection of software services, apps, and connectors
|
||||
> that work together to turn your unrelated sources of data into coherent,
|
||||
> visually immersive, and interactive insights.
|
||||
>
|
||||
> {{% cite %}}-- [Microsoft Power BI documentation](https://learn.microsoft.com/en-us/power-bi/fundamentals/power-bi-overview){{% /cite %}}
|
||||
|
||||
> [!Important]
|
||||
> These instructions are for Power BI Desktop only; it uses a custom connector.
|
||||
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Install the Power BI connector](#install-the-power-bi-connector)
|
||||
- [Install the Arrow Flight SQL ODBC Driver](#install-the-arrow-flight-sql-odbc-driver)
|
||||
- [Enable the connector in Power BI](#enable-the-connector-in-power-bi)
|
||||
- [Connect Power BI to InfluxDB](#connect-power-bi-to-influxdb)
|
||||
- [Query and visualize data](#query-and-visualize-data)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Windows operating system**: The custom connector requires Windows
|
||||
(macOS users can use virtualization software like [Parallels](https://www.parallels.com/))
|
||||
- **Power BI Desktop**: [Download and install Power BI Desktop](https://powerbi.microsoft.com/desktop/)
|
||||
(A free trial is available)
|
||||
- **{{% product-name %}}**: A running instance with data to query
|
||||
- **Database token**: Your {{% show-in "cloud-dedicated, clustered" %}}{{% token-link "database" %}}{{% /show-in %}}{{% show-in "cloud-serverless" %}}{{% token-link %}}{{% /show-in %}}{{% show-in "core, enterprise" %}}{{% token-link "admin" "database" %}}{{% /show-in %}}{{% show-in "enterprise" %}} with query permissions for the target database{{% /show-in %}}
|
||||
|
||||
The following steps guide you through downloading and installing the Arrow Flight SQL ODBC Driver and the InfluxDB 3 custom connector.
|
||||
|
||||
## Install the Power BI connector
|
||||
|
||||
The InfluxDB 3 custom connector for Power BI Desktop enables you to connect to
|
||||
{{% product-name %}} and query data using SQL.
|
||||
|
||||
### Install the Arrow Flight SQL ODBC Driver
|
||||
|
||||
The custom connector requires the Arrow Flight SQL ODBC Driver.
|
||||
|
||||
<a class="btn" href="https://docs.influxdata.com/downloads/arrow-flight-sql-odbc-0.9.7.1195-win64.msi">Download the Arrow Flight SQL ODBC driver</a>
|
||||
|
||||
Or use PowerShell to download and install:
|
||||
|
||||
{{% code-placeholders "YOUR_USER" %}}
|
||||
```powershell
|
||||
# Download the driver
|
||||
Invoke-WebRequest -Uri "https://docs.influxdata.com/downloads/arrow-flight-sql-odbc-0.9.7.1195-win64.msi" `
|
||||
-OutFile "C:\Users\YOUR_USER\Downloads\arrow-flight-sql-odbc-0.9.7.1195-win64.msi"
|
||||
|
||||
# Mark as trusted
|
||||
Unblock-File "C:\Users\YOUR_USER\Downloads\arrow-flight-sql-odbc-0.9.7.1195-win64.msi"
|
||||
|
||||
# Install
|
||||
Start-Process msiexec.exe -Wait -ArgumentList '/i "C:\Users\YOUR_USER\Downloads\arrow-flight-sql-odbc-0.9.7.1195-win64.msi"'
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
|
||||
Replace the following:
|
||||
|
||||
- {{% code-placeholder-key %}}`YOUR_USER`{{% /code-placeholder-key %}}: Your Windows username
|
||||
|
||||
Follow the installation wizard using default settings.
|
||||
|
||||
> [!Note]
|
||||
> For more information about the Arrow Flight SQL ODBC Driver, see the [Dremio documentation](https://docs.dremio.com/current/client-applications/drivers/arrow-flight-sql-odbc-driver/).
|
||||
|
||||
### Install the Power BI connector file
|
||||
|
||||
<a class="btn" href="https://docs.influxdata.com/downloads/InfluxDB.pqx">Download the InfluxDB 3 Power BI connector</a>
|
||||
|
||||
Or use PowerShell to download:
|
||||
|
||||
{{% code-placeholders "YOUR_USER" %}}
|
||||
```powershell
|
||||
# Download the connector
|
||||
Invoke-WebRequest -Uri "https://docs.influxdata.com/downloads/InfluxDB.pqx" `
|
||||
-OutFile "C:\Users\YOUR_USER\Downloads\InfluxDB.pqx"
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
|
||||
Replace the following:
|
||||
|
||||
- {{% code-placeholder-key %}}`YOUR_USER`{{% /code-placeholder-key %}}: Your Windows username
|
||||
|
||||
#### Install the connector
|
||||
|
||||
Move the `.pqx` connector file to the Power BI custom connectors directory:
|
||||
|
||||
1. Create the custom connectors folder if it doesn't exist:
|
||||
|
||||
```powershell
|
||||
mkdir "$env:USERPROFILE\Documents\Power BI Desktop\Custom Connectors"
|
||||
```
|
||||
|
||||
2. Move the connector file to the custom connectors folder:
|
||||
|
||||
{{% code-placeholders "YOUR_USER" %}}
|
||||
```powershell
|
||||
Move-Item "C:\Users\YOUR_USER\Downloads\InfluxDB.pqx" `
|
||||
"$env:USERPROFILE\Documents\Power BI Desktop\Custom Connectors\"
|
||||
```
|
||||
{{% /code-placeholders %}}
|
||||
|
||||
Replace the following:
|
||||
|
||||
- {{% code-placeholder-key %}}`YOUR_USER`{{% /code-placeholder-key %}}: Your Windows username
|
||||
|
||||
## Enable the connector in Power BI
|
||||
|
||||
To use custom connectors, you must adjust Power BI Desktop's security settings:
|
||||
|
||||
1. Open Power BI Desktop
|
||||
2. Select **File** > **Options and settings** > **Options**
|
||||
3. Navigate to **Security** under **GLOBAL**
|
||||
4. Under **Data Extensions**, select **(Not Recommended) Allow any extension to
|
||||
load without validation or warning**
|
||||
5. Click **OK**
|
||||
6. **Restart Power BI Desktop** for the changes to take effect
|
||||
|
||||
> [!Warning]
|
||||
> #### Security considerations
|
||||
> Enabling uncertified extensions allows any custom connector to load.
|
||||
> Only enable this setting if you trust the connectors you're installing.
|
||||
|
||||
## Connect Power BI to InfluxDB
|
||||
|
||||
After installing the connector and restarting Power BI Desktop:
|
||||
|
||||
1. Open **Power BI Desktop**
|
||||
2. Click **Get Data** > **More**
|
||||
3. Search for **InfluxDB 3** and select it
|
||||
4. Click **Connect**
|
||||
5. In the **InfluxDB 3** connection dialog, configure the following:
|
||||
|
||||
- **Server**: Your {{% product-name %}} URL without the port, (for example,
|
||||
{{% show-in "cloud-serverless" %}}`https://us-west-2-1.aws.cloud2.influxdata.com`{{% /show-in %}}{{% show-in "cloud-dedicated" %}}`https://cluster-id.a.influxdb.io`{{% /show-in %}}{{% show-in "clustered" %}}`https://cluster-host.com`{{% /show-in %}}{{% show-in "enterprise,core" %}}`http://localhost`{{% /show-in %}})
|
||||
- **Database**: Your database name
|
||||
- **Port**: Your server port (for example, {{% show-in "cloud-serverless,cloud-dedicated,clustered" %}}`443` (HTTPS){{% /show-in %}}{{% show-in "enterprise,core" %}}`8181` (default){{% /show-in %}})
|
||||
- **Native Query** (optional): Enter a SQL query to limit the data loaded
|
||||
|
||||
6. Select **DirectQuery** as the **Data Connectivity mode**
|
||||
7. Click **OK**
|
||||
8. When prompted for credentials:
|
||||
- Select **Basic** authentication
|
||||
- **Username**: Leave blank or enter any value
|
||||
- **Password**: Enter your {{% show-in "cloud-dedicated, clustered" %}}{{% token-link "database" %}}{{% /show-in %}}{{% show-in "cloud-serverless" %}}{{% token-link %}}{{% /show-in %}}{{% show-in "core, enterprise" %}}{{% token-link "admin" "database" %}}{{% /show-in %}}{{% show-in "enterprise" %}} with query permissions for the target database{{% /show-in %}}
|
||||
9. Click **Connect**
|
||||
10. Preview your data and click **Load**
|
||||
|
||||
> [!Important]
|
||||
> #### Limit query size for optimal performance
|
||||
> {{% product-name %}} can handle high throughput and dimensional data.
|
||||
> To ensure Power BI can successfully process data, limit query size by:
|
||||
> - Using a `LIMIT` clause
|
||||
> - Specifying time ranges with `WHERE time >= ...`
|
||||
> - Filtering by specific columns or tags
|
||||
|
||||
## Query and visualize data
|
||||
|
||||
### Use Native Queries
|
||||
|
||||
When connecting to InfluxDB 3, you can use the **Native Query** option to
|
||||
execute custom SQL queries:
|
||||
|
||||
1. In the connection dialog, enable **Native Query**
|
||||
2. Enter your query in the provided field:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
time,
|
||||
temp,
|
||||
room
|
||||
FROM
|
||||
home
|
||||
WHERE
|
||||
time >= now() - INTERVAL '7 days'
|
||||
ORDER BY
|
||||
time DESC
|
||||
LIMIT 1000
|
||||
```
|
||||
|
||||
3. Select **DirectQuery** as the connectivity mode
|
||||
4. Click **OK** to load the data
|
||||
|
||||
### Create visualizations
|
||||
|
||||
After loading data, Power BI displays your dataset in the **Fields** pane.
|
||||
|
||||
#### View data in a table
|
||||
|
||||
1. In the **Visualizations** pane, select the **Table** visualization
|
||||
2. In the **Fields** pane, select the columns to display:
|
||||
- **time**: Timestamp column
|
||||
- **room**: Tag column
|
||||
- **temp**: Field column
|
||||
3. By default, Power BI summarizes numeric fields.
|
||||
To display raw values:
|
||||
- Select the field in the **Fields** or **Visualizations** pane
|
||||
- Go to the **Modeling** tab
|
||||
- Change **Default Summarization** to **Don't Summarize**
|
||||
|
||||
#### Create time series visualizations
|
||||
|
||||
1. In the **Visualizations** pane, select a visualization type
|
||||
(for example, **Line chart**)
|
||||
2. Drag fields to the appropriate areas:
|
||||
- **X-axis**: `time` field
|
||||
- **Y-axis**: Measurement fields (for example, `temp`)
|
||||
- **Legend**: Tag fields (for example, `room`)
|
||||
3. Use the **Filters** pane to apply additional filters
|
||||
4. Configure visualization properties in the **Format** pane
|
||||
5. Save your report
|
||||
|
||||
### Time series best practices
|
||||
|
||||
- Always include time range filters in your queries to limit data volume
|
||||
- Use the `time` column for time-based visualizations
|
||||
- Apply Power BI's date hierarchy features with the `time` column
|
||||
- Select only the columns you need to improve query performance
|
||||
- Use the `LIMIT` clause to restrict the number of rows returned
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connector not found
|
||||
|
||||
If Power BI Desktop doesn't show the InfluxDB 3 connector:
|
||||
|
||||
- Verify the `.pqx` file is in the correct location:
|
||||
`Documents\Power BI Desktop\Custom Connectors\`
|
||||
- Ensure you enabled custom connectors in Power BI security settings
|
||||
- Restart Power BI Desktop after copying the connector file
|
||||
|
||||
### Connection errors
|
||||
|
||||
If you encounter connection errors:
|
||||
|
||||
- Verify your {{% product-name %}} instance is accessible
|
||||
- Check that the host URL and port are correct
|
||||
- Local instances typically use `http://localhost:8181`
|
||||
- {{% show-in "cloud-serverless,cloud-dedicated" %}}{{% product-name %}} instances use cluster-specific URLs{{% /show-in %}}
|
||||
- Ensure your token has query permissions for the specified database
|
||||
- Verify firewall rules allow connections on the specified port
|
||||
|
||||
### Authentication errors
|
||||
|
||||
If authentication fails:
|
||||
|
||||
- Verify your database token is valid and not expired
|
||||
- {{% show-in "enterprise" %}}Ensure the token has permissions for the target database{{% /show-in %}}
|
||||
- Check that you entered the token in the **Password** field
|
||||
- Leave the **Username** field blank or enter any value
|
||||
|
||||
### Query performance
|
||||
|
||||
For better query performance:
|
||||
|
||||
- Always use `WHERE` clauses to filter data before loading
|
||||
- Include time range filters to limit the data scanned
|
||||
- Select only the columns you need
|
||||
- Use the `LIMIT` clause to restrict result size
|
||||
- Consider using **DirectQuery** mode instead of **Import** for large datasets
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
Use [Grafana](https://grafana.com/) to query and visualize data stored in
|
||||
{{% product-name %}}.
|
||||
Use [Grafana](https://grafana.com/) or [Grafana Cloud](https://grafana.com/products/cloud/)
|
||||
to query and visualize data from {{% product-name %}}.
|
||||
|
||||
> [!Note]
|
||||
> {{< influxdb-version-detector >}}
|
||||
|
||||
> [Grafana] enables you to query, visualize, alert on, and explore your metrics,
|
||||
> logs, and traces wherever they are stored.
|
||||
|
|
@ -8,24 +11,50 @@ Use [Grafana](https://grafana.com/) to query and visualize data stored in
|
|||
>
|
||||
> {{% cite %}}-- [Grafana documentation](https://grafana.com/docs/grafana/latest/introduction/){{% /cite %}}
|
||||
|
||||
- [Install Grafana or login to Grafana Cloud](#install-grafana-or-login-to-grafana-cloud)
|
||||
- [Install Grafana or log in to Grafana Cloud](#install-grafana-or-log-in-to-grafana-cloud)
|
||||
- [InfluxDB data source](#influxdb-data-source)
|
||||
- [Before you begin](#before-you-begin)
|
||||
- [Create an InfluxDB data source](#create-an-influxdb-data-source)
|
||||
- [Query InfluxDB with Grafana](#query-influxdb-with-grafana)
|
||||
- [Build visualizations with Grafana](#build-visualizations-with-grafana)
|
||||
- [Query and visualize data](#query-and-visualize-data)
|
||||
|
||||
## Install Grafana or login to Grafana Cloud
|
||||
## Install Grafana or log in to Grafana Cloud
|
||||
|
||||
If using the open source version of **Grafana**, follow the
|
||||
[Grafana installation instructions](https://grafana.com/docs/grafana/latest/setup-grafana/installation/)
|
||||
to install Grafana for your operating system.
|
||||
If using **Grafana Cloud**, log in to your Grafana Cloud instance.
|
||||
|
||||
{{% show-in "core,enterprise" %}}
|
||||
> [!Note]
|
||||
> #### Using Grafana Cloud with a local InfluxDB instance
|
||||
>
|
||||
> If you need to keep your database local, consider running Grafana locally instead of using Grafana Cloud,
|
||||
> as this avoids the need to expose your database to the internet.
|
||||
>
|
||||
> To use InfluxDB running on your private network with Grafana Cloud, you must
|
||||
> [configure a private data source](https://grafana.com/docs/grafana-cloud/data-sources/private-data-sources/).
|
||||
> See the Grafana documentation for instructions on configuring a Grafana Cloud private data source
|
||||
> with {{% product-name %}} running on `http://localhost:8181`.
|
||||
{{% /show-in %}}
|
||||
|
||||
{{% show-in "clustered" %}}
|
||||
> [!Note]
|
||||
> #### Using Grafana Cloud with a local InfluxDB instance
|
||||
>
|
||||
> If you need to keep your database local, consider running Grafana locally instead of using Grafana Cloud,
|
||||
> as this avoids the need to expose your database to the internet.
|
||||
>
|
||||
> To use InfluxDB running on your private network with Grafana Cloud, you must
|
||||
> [configure a private data source](https://grafana.com/docs/grafana-cloud/data-sources/private-data-sources/).
|
||||
> See the Grafana documentation for instructions on configuring a Grafana Cloud private data source
|
||||
> with {{% product-name %}} running on `http://localhost`.
|
||||
{{% /show-in %}}
|
||||
|
||||
## InfluxDB data source
|
||||
|
||||
The InfluxDB data source plugin is included in the Grafana core distribution.
|
||||
Use the plugin to query and visualize data stored in {{< product-name >}} with
|
||||
both InfluxQL and SQL.
|
||||
Use the plugin to query and visualize data from {{< product-name >}} with
|
||||
both SQL and InfluxQL.
|
||||
|
||||
> [!Note]
|
||||
> #### Grafana 10.3+
|
||||
|
|
@ -33,18 +62,41 @@ both InfluxQL and SQL.
|
|||
> The instructions below are for **Grafana 10.3+** which introduced the newest
|
||||
> version of the InfluxDB core plugin.
|
||||
> The updated plugin includes **SQL support** for InfluxDB 3-based products such
|
||||
> as {{< product-name >}}.
|
||||
> as {{< product-name >}}, and the interface dynamically adapts based on your product and query language selections.
|
||||
|
||||
## Before you begin
|
||||
|
||||
**Prerequisites:**
|
||||
- Grafana 10.3 or later
|
||||
- Administrator role in Grafana
|
||||
- {{% show-in "cloud-serverless" %}}An [API token](/influxdb3/version/admin/tokens/) with read access to the bucket{{% /show-in %}}{{% show-in "cloud-dedicated,clustered" %}}A [database token](/influxdb3/version/admin/tokens/#database-tokens) with read access to the database{{% /show-in %}}{{% show-in "core,enterprise" %}}Your {{% token-link "admin" "database" %}} with read access to the database{{% /show-in %}}
|
||||
|
||||
### Quick reference: {{< product-name >}} configuration
|
||||
|
||||
| Configuration | Value |
|
||||
|:------------- |:----- |
|
||||
| **Product selection** | {{% hide-in "core,enterprise" %}}**{{% product-name %}}**{{% /hide-in %}}{{% show-in "core" %}}**InfluxDB Enterprise 3.x** _(currently, no **Core** menu option)_{{% /show-in %}}{{% show-in "enterprise" %}}**InfluxDB Enterprise 3.x**{{% /show-in %}} |
|
||||
| **URL** | {{% show-in "cloud-dedicated,clustered" %}} Cluster URL{{% /show-in %}}{{% show-in "cloud-serverless" %}} [Region URL](/influxdb3/cloud-serverless/reference/regions/)--for example, `https://us-west-2-1.aws.cloud2.influxdata.com`{{% /show-in %}}{{% show-in "core,enterprise" %}}Server URL{{% /show-in %}}{{% hide-in "cloud-serverless" %}}--for example, `https://{{< influxdb/host >}}`{{% /hide-in %}} |
|
||||
| **Query languages** | SQL (requires HTTP/2), InfluxQL |
|
||||
| **Authentication** | {{% show-in "cloud-serverless" %}}Required (API token){{% /show-in %}}{{% show-in "core" %}}Admin token (if authentication is enabled){{% /show-in %}}{{% show-in "enterprise" %}}Admin or database token (if authentication is enabled){{% /show-in %}}{{% show-in "cloud-dedicated,clustered" %}}Required (database token){{% /show-in %}} |
|
||||
| **Database/Bucket** | {{% show-in "cloud-serverless" %}}Bucket name{{% /show-in %}}{{% hide-in "cloud-serverless" %}}Database name{{% /hide-in %}} |
|
||||
|
||||
## Create an InfluxDB data source
|
||||
|
||||
Which data source you create depends on which query language you want to use to
|
||||
query {{% product-name %}}:
|
||||
1. In your Grafana interface, click **Connections** in the left sidebar.
|
||||
2. Click **Data sources**.
|
||||
3. Click **Add new data source**.
|
||||
4. Search for and select **InfluxDB**. The InfluxDB data source configuration page displays.
|
||||
5. In the **Settings** tab, configure the following:
|
||||
|
||||
1. In your Grafana user interface (UI), navigate to **Data Sources**.
|
||||
2. Click **Add new data source**.
|
||||
3. Search for and select the **InfluxDB** plugin.
|
||||
4. Provide a name for your data source.
|
||||
5. Under **Query Language**, select either **SQL** or **InfluxQL**:
|
||||
- **Name**: A descriptive name for your data source
|
||||
- **URL**: Your {{% product-name %}}{{% show-in "cloud-dedicated,clustered" %}} cluster URL{{% /show-in %}}{{% show-in "cloud-serverless" %}} [region URL](/influxdb3/cloud-serverless/reference/regions/)--for example, `https://us-west-2-1.aws.cloud2.influxdata.com`{{% /show-in %}}{{% show-in "core,enterprise" %}} server URL{{% /show-in %}}{{% hide-in "cloud-serverless" %}}--for example, `https://{{< influxdb/host >}}`{{% /hide-in %}}
|
||||
- **Product**: From the dropdown, select {{% hide-in "core,enterprise" %}}**{{% product-name %}}**{{% /hide-in %}}{{% show-in "core" %}}**InfluxDB Enterprise 3.x** _(currently, no **Core** menu option)_{{% /show-in %}}{{% show-in "core,enterprise" %}}**InfluxDB Enterprise 3.x**{{% /show-in %}}
|
||||
- **Query Language**: Select **SQL** or **InfluxQL**
|
||||
|
||||
### Configure database settings
|
||||
|
||||
The fields in this section change based on your query language selection.
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
|
|
@ -54,75 +106,79 @@ query {{% product-name %}}:
|
|||
{{% tab-content %}}
|
||||
<!--------------------------------- BEGIN SQL --------------------------------->
|
||||
|
||||
When creating an InfluxDB data source that uses SQL to query data:
|
||||
#### SQL configuration
|
||||
|
||||
1. Under **HTTP**:
|
||||
When you select **SQL** as the query language, configure the following fields:
|
||||
|
||||
- **URL**: Provide your {{% show-in "cloud-serverless" %}}[{{< product-name >}} region URL](/influxdb3/version/reference/regions/){{% /show-in %}}
|
||||
{{% hide-in "cloud-serverless" %}}{{% product-name omit=" Clustered" %}} cluster URL{{% /hide-in %}} using the HTTPS protocol:
|
||||
- **Database**: {{% show-in "cloud-serverless" %}}Your [bucket](/influxdb3/version/admin/buckets/) name. In {{< product-name >}}, buckets function as databases.{{% /show-in %}}{{% hide-in "cloud-serverless" %}}Your [database](/influxdb3/version/admin/databases/) name.{{% /hide-in %}}
|
||||
|
||||
```
|
||||
https://{{< influxdb/host >}}
|
||||
```
|
||||
2. Under **InfluxDB Details**:
|
||||
- **Token**: {{% show-in "cloud-serverless" %}}An [API token](/influxdb3/version/admin/tokens/) with read access to the bucket{{% /show-in %}}{{% show-in "cloud-dedicated,clustered" %}}A [database token](/influxdb3/version/admin/tokens/#database-tokens) with read access to the database{{% /show-in %}}{{% show-in "core,enterprise" %}}Your {{% token-link "admin" "database" %}} with read access to the database{{% /show-in %}}
|
||||
|
||||
- **Database**: Provide a default {{% show-in "cloud-serverless" %}}[bucket](/influxdb3/version/admin/buckets/) name to query. In {{< product-name >}}, a bucket functions as a database.{{% /show-in %}}{{% hide-in "cloud-serverless" %}}[database](/influxdb3/version/admin/databases/) name to query.{{% /hide-in %}}
|
||||
- **Token**: Provide {{% show-in "cloud-serverless" %}}an [API token](/influxdb3/version/admin/tokens/) with read access to the buckets you want to query.{{% /show-in %}}{{% hide-in "cloud-serverless" %}}a [database token](/influxdb3/version/admin/tokens/#database-tokens) with read access to the databases you want to query.{{% /hide-in %}}
|
||||
3. Click **Save & test**.
|
||||
{{% show-in "cloud-serverless" %}}{{< img-hd src="/img/influxdb3/cloud-serverless-grafana-product-dropdown-sql.png" alt="SQL configuration for {{% product-name %}}" />}}{{% /show-in %}}
|
||||
{{% show-in "cloud-dedicated" %}}{{< img-hd src="/img/influxdb3/cloud-dedicated-grafana-product-dropdown-sql.png" alt="SQL configuration for {{% product-name %}}" />}}{{% /show-in %}}
|
||||
{{% show-in "clustered" %}}{{< img-hd src="/img/influxdb3/cluster-grafana-product-dropdown-sql.png" alt="SQL configuration for {{% product-name %}}" />}}{{% /show-in %}}
|
||||
{{% show-in "core, enterprise" %}}{{< img-hd src="/img/influxdb3/enterprise-v3-grafana-product-dropdown-sql.png" alt="SQL configuration for {{% product-name %}}" />}}{{% /show-in %}}
|
||||
|
||||
{{% show-in "cloud-serverless" %}}{{< img-hd src="/img/influxdb3/cloud-serverless-grafana-influxdb-data-source-sql.png" alt="Grafana InfluxDB data source for InfluxDB Cloud Serverless that uses SQL" />}}{{% /show-in %}}
|
||||
{{% show-in "cloud-dedicated" %}}{{< img-hd src="/img/influxdb/cloud-dedicated-grafana-influxdb-data-source-sql.png" alt="Grafana InfluxDB data source for InfluxDB Cloud Dedicated that uses SQL" />}}{{% /show-in %}}
|
||||
{{% show-in "clustered" %}}{{< img-hd src="/img/influxdb3/clustered-grafana-influxdb-data-source-sql.png" alt="Grafana InfluxDB data source for InfluxDB Clustered that uses SQL" />}}{{% /show-in %}}
|
||||
> [!Important]
|
||||
> #### Grafana queries through a proxy require HTTP/2
|
||||
>
|
||||
> For SQL queries, Grafana uses the Flight SQL protocol (gRPC) to query {{% product-name %}}, which requires **HTTP/2**.
|
||||
> If you query {{% product-name %}} through a proxy (such as HAProxy, nginx, or a load balancer),
|
||||
> verify that your proxy is configured to support HTTP/2.
|
||||
> Without HTTP/2 support, SQL queries through Grafana will fail to connect.
|
||||
>
|
||||
> InfluxQL queries use HTTP/1.1 and are not affected by this requirement.
|
||||
|
||||
Click **Save & test**. Grafana attempts to connect to {{% product-name %}} and returns the result of the test.
|
||||
|
||||
<!---------------------------------- END SQL ---------------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{% tab-content %}}
|
||||
<!------------------------------- BEGIN INFLUXQL ------------------------------>
|
||||
|
||||
When creating an InfluxDB data source that uses InfluxQL to query data:
|
||||
#### InfluxQL configuration
|
||||
|
||||
{{% show-in "cloud-serverless" %}}
|
||||
> [!Note]
|
||||
> #### Map databases and retention policies to buckets
|
||||
>
|
||||
> To query {{% product-name %}} with InfluxQL, first map database and retention policy
|
||||
> (DBRP) combinations to your InfluxDB Cloud buckets. For more information, see
|
||||
> [Map databases and retention policies to buckets](/influxdb3/version/query-data/influxql/dbrp/).
|
||||
> [!Important]
|
||||
> #### DBRP mapping required
|
||||
>
|
||||
> To query {{% product-name %}} with InfluxQL, you must first map database and
|
||||
> retention policy (DBRP) combinations to your InfluxDB Cloud buckets. The
|
||||
> configuration form displays a warning if DBRP mapping is not configured.
|
||||
>
|
||||
> For more information, see [Map databases and retention policies to buckets](/influxdb3/version/query-data/influxql/dbrp/).
|
||||
{{% /show-in %}}
|
||||
|
||||
1. Under **HTTP**:
|
||||
When you select **InfluxQL** as the query language, configure the following fields:
|
||||
|
||||
- **URL**: Provide your {{% show-in "cloud-serverless" %}}[{{< product-name >}} region URL](/influxdb3/version/reference/regions/){{% /show-in %}}{{% hide-in "cloud-serverless" %}}{{% product-name omit=" Clustered" %}} cluster URL{{% /hide-in %}}
|
||||
using the HTTPS protocol:
|
||||
- **Database**: {{% show-in "cloud-serverless" %}}The database name mapped to your InfluxDB bucket.{{% /show-in %}}{{% hide-in "cloud-serverless" %}}Your [database](/influxdb3/version/admin/databases/) name.{{% /hide-in %}}
|
||||
|
||||
```
|
||||
https://{{< influxdb/host >}}
|
||||
```
|
||||
2. Under **InfluxDB Details**:
|
||||
- **User**: A username (can be any non-empty value).
|
||||
|
||||
- **Database**: Provide a {{% show-in "cloud-serverless" %}}database name to query.
|
||||
Use the database name that is mapped to your InfluxDB bucket{{% /show-in %}}{{% hide-in "cloud-serverless" %}}default [database](/influxdb3/version/admin/databases/) name to query{{% /hide-in %}}.
|
||||
- **User**: Provide an arbitrary string.
|
||||
_This credential is ignored when querying {{% product-name %}}, but it cannot be empty._
|
||||
- **Password**: Provide {{% show-in "cloud-serverless" %}}an [API token](/influxdb3/version/admin/tokens/) with read access to the buckets you want to query{{% /show-in %}}{{% hide-in "cloud-serverless" %}}a [database token](/influxdb3/version/admin/tokens/#database-tokens) with read access to the databases you want to query{{% /hide-in %}}.
|
||||
- **HTTP Method**: Choose one of the available HTTP request methods to use when querying data:
|
||||
- **Password**: {{% show-in "cloud-serverless" %}}Your [API token](/influxdb3/version/admin/tokens/) with read access to the bucket.{{% /show-in %}}{{% hide-in "cloud-serverless" %}}Your [database token](/influxdb3/version/admin/tokens/#database-tokens) with read access to the database.{{% /hide-in %}}
|
||||
|
||||
- **POST** ({{< req text="Recommended" >}})
|
||||
- **GET**
|
||||
3. Click **Save & test**.
|
||||
- **HTTP Method**: Select **POST** (recommended) or **GET**
|
||||
|
||||
{{% show-in "cloud-dedicated" %}}{{< img-hd src="/img/influxdb/cloud-dedicated-grafana-influxdb-data-source-influxql.png" alt="Grafana InfluxDB data source for InfluxDB Cloud Dedicated using InfluxQL" />}}{{% /show-in %}}
|
||||
{{% show-in "cloud-serverless" %}}{{< img-hd src="/img/influxdb3/cloud-serverless-grafana-influxdb-data-source-influxql.png" alt="Grafana InfluxDB data source for InfluxDB Cloud Serverless using InfluxQL" />}}{{% /show-in %}}
|
||||
{{% show-in "clustered" %}}{{< img-hd src="/img/influxdb3/clustered-grafana-influxdb-data-source-influxql.png" alt="Grafana InfluxDB data source for InfluxDB Clustered using InfluxQL" />}}{{% /show-in %}}
|
||||
{{% show-in "cloud-serverless" %}}{{< img-hd src="/img/influxdb3/cloud-serverless-grafana-product-dropdown-influxql.png" alt="InfluxQL configuration for {{% product-name %}} with DBRP warning" />}}{{% /show-in %}}
|
||||
{{% show-in "cloud-dedicated" %}}{{< img-hd src="/img/influxdb3/cloud-dedicated-grafana-product-dropdown-influxql.png" alt="InfluxQL configuration for {{% product-name %}} with DBRP warning" />}}{{% /show-in %}}
|
||||
{{% show-in "clustered" %}}{{< img-hd src="/img/influxdb3/cluster-grafana-product-dropdown-influxql.png" alt="InfluxQL configuration for {{% product-name %}} with DBRP warning" />}}{{% /show-in %}}
|
||||
<!-- Grafana hasn't added Core as a product option yet -->
|
||||
{{% show-in "enterprise" %}}{{< img-hd src="/img/influxdb3/enterprise-v3-grafana-product-dropdown-influxql.png" alt="InfluxQL configuration for {{% product-name %}} with DBRP warning" />}}{{% /show-in %}}
|
||||
|
||||
Click **Save & test**. Grafana attempts to connect to {{% product-name %}} and returns the result of the test.
|
||||
|
||||
<!-------------------------------- END INFLUXQL ------------------------------->
|
||||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
## Query InfluxDB with Grafana
|
||||
## Query and visualize data
|
||||
|
||||
With your InfluxDB connection configured, use Grafana to query and visualize time series data.
|
||||
|
||||
### Query InfluxDB with Grafana
|
||||
|
||||
After you [configure and save an InfluxDB datasource](#create-an-influxdb-data-source),
|
||||
use Grafana to build, run, and inspect queries against your InfluxDB {{% show-in "cloud-serverless" %}}bucket{{% /show-in %}}{{% hide-in "cloud-serverless" %}}database{{% /hide-in %}}.
|
||||
use Grafana to build, run, and inspect queries against {{% show-in "cloud-serverless" %}}your InfluxDB bucket{{% /show-in %}}{{% hide-in "cloud-serverless" %}}{{% product-name %}}{{% /hide-in %}}.
|
||||
|
||||
{{< tabs-wrapper >}}
|
||||
{{% tabs %}}
|
||||
|
|
@ -139,12 +195,12 @@ use Grafana to build, run, and inspect queries against your InfluxDB {{% show-in
|
|||
1. Click **Explore**.
|
||||
2. In the dropdown, select the saved InfluxDB data source to query.
|
||||
3. Use the SQL query form to build your query:
|
||||
- **Table**: Select the measurement to query.
|
||||
- **Table**: Select the table (measurement) to query.
|
||||
- **Column**: Select one or more fields and tags to return as columns in query results.
|
||||
|
||||
|
||||
With SQL, select the `time` column to include timestamps with the data.
|
||||
Grafana relies on the `time` column to correctly graph time series data.
|
||||
|
||||
|
||||
- _**Optional:**_ Toggle **filter** to generate **WHERE** clause statements.
|
||||
- **WHERE**: Configure condition expressions to include in the `WHERE` clause.
|
||||
|
||||
|
|
@ -190,12 +246,14 @@ use Grafana to build, run, and inspect queries against your InfluxDB {{% show-in
|
|||
{{% /tab-content %}}
|
||||
{{< /tabs-wrapper >}}
|
||||
|
||||
{{< youtube "rSsouoNsNDs" >}}
|
||||
With your InfluxDB connection configured, use Grafana to query and visualize time series data.
|
||||
|
||||
To learn about query management and inspection in Grafana, see the
|
||||
[Grafana Explore documentation](https://grafana.com/docs/grafana/latest/explore/).
|
||||
|
||||
## Build visualizations with Grafana
|
||||
### Build visualizations with Grafana
|
||||
|
||||
For a comprehensive walk-through of creating visualizations with
|
||||
Grafana, see the [Grafana documentation](https://grafana.com/docs/grafana/latest/).
|
||||
Grafana, see the [Grafana documentation](https://grafana.com/docs/grafana/latest/).
|
||||
|
||||
### Query inspection in Grafana
|
||||
|
||||
To learn more about query management and inspection in Grafana, see the
|
||||
[Grafana Explore documentation](https://grafana.com/docs/grafana/latest/explore/).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
title: Test InfluxDB Version Detector
|
||||
description: Test page for the InfluxDB version detector component
|
||||
weight: 1000
|
||||
test_only: true # Custom parameter to indicate test-only content
|
||||
---
|
||||
|
||||
This is a test page for the InfluxDB version detector component.
|
||||
|
||||
{{< influxdb-version-detector >}}
|
||||
|
||||
## About this component
|
||||
|
||||
This interactive component helps users identify which InfluxDB product they're using by:
|
||||
- Checking URL patterns
|
||||
- Analyzing ping response headers
|
||||
- Asking guided questions about their setup
|
||||
- Providing ranked results based on their answers
|
||||
|
|
@ -0,0 +1,861 @@
|
|||
/// <reference types="cypress" />
|
||||
|
||||
/**
|
||||
* InfluxDB Version Detector E2E Test Suite
|
||||
*
|
||||
* COMPREHENSIVE TEST SCENARIOS CHECKLIST:
|
||||
*
|
||||
* URL Detection Scenarios:
|
||||
* -------------------------
|
||||
* Cloud URLs (Definitive Detection):
|
||||
* - [ ] Dedicated: https://cluster-id.influxdb.io → InfluxDB Cloud Dedicated (confidence 1.0)
|
||||
* - [ ] Serverless US: https://us-east-1-1.aws.cloud2.influxdata.com → InfluxDB Cloud Serverless
|
||||
* - [ ] Serverless EU: https://eu-central-1-1.aws.cloud2.influxdata.com → InfluxDB Cloud Serverless
|
||||
* - [ ] Cloud TSM: https://us-west-2-1.aws.cloud2.influxdata.com → InfluxDB Cloud v2 (TSM)
|
||||
* - [ ] Cloud v1: https://us-west-1-1.influxcloud.net → InfluxDB Cloud v1
|
||||
*
|
||||
* Localhost URLs (Port-based Detection):
|
||||
* - [ ] Core/Enterprise Port: http://localhost:8181 → Should suggest ping test
|
||||
* - [ ] OSS Port: http://localhost:8086 → Should suggest version check
|
||||
* - [ ] Custom Port: http://localhost:9999 → Should fall back to questionnaire
|
||||
*
|
||||
* Edge Cases:
|
||||
* - [ ] Empty URL: Submit without entering URL → Should show error
|
||||
* - [ ] Invalid URL: "not-a-url" → Should fall back to questionnaire
|
||||
* - [ ] Cloud keyword: "cloud 2" → Should start questionnaire with cloud context
|
||||
* - [ ] Mixed case: HTTP://LOCALHOST:8181 → Should detect port correctly
|
||||
*
|
||||
* Airgapped/Manual Analysis Scenarios:
|
||||
* -------------------------------------
|
||||
* Ping Headers Analysis:
|
||||
* - [ ] v3 Core headers: x-influxdb-build: core → InfluxDB 3 Core
|
||||
* - [ ] v3 Enterprise headers: x-influxdb-build: enterprise → InfluxDB 3 Enterprise
|
||||
* - [ ] v2 OSS headers: X-Influxdb-Version: 2.7.8 → InfluxDB OSS 2.x
|
||||
* - [ ] v1 headers: X-Influxdb-Version: 1.8.10 → InfluxDB OSS 1.x
|
||||
* - [ ] 401 Response: Headers showing 401/403 → Should show auth required message
|
||||
* - [ ] Empty headers: Submit without text → Should show error
|
||||
* - [ ] Example content: Submit with placeholder text → Should show error
|
||||
*
|
||||
* Docker Output Analysis:
|
||||
* - [ ] Explicit v3 Core: "InfluxDB 3 Core" in output → InfluxDB 3 Core
|
||||
* - [ ] Explicit v3 Enterprise: "InfluxDB 3 Enterprise" in output → InfluxDB 3 Enterprise
|
||||
* - [ ] Generic v3: x-influxdb-version: 3.1.0 but no build header → Core or Enterprise
|
||||
* - [ ] v2 version: "InfluxDB v2.7.8" in output → InfluxDB OSS 2.x
|
||||
* - [ ] v1 OSS: "InfluxDB v1.8.10" in output → InfluxDB OSS 1.x
|
||||
* - [ ] v1 Enterprise: "InfluxDB 1.8.10" + "Enterprise" → InfluxDB Enterprise
|
||||
* - [ ] Empty output: Submit without text → Should show error
|
||||
* - [ ] Example content: Submit with placeholder text → Should show error
|
||||
*
|
||||
* Questionnaire Flow Scenarios:
|
||||
* ------------------------------
|
||||
* License-based Paths:
|
||||
* - [ ] Free → Self-hosted → Recent → SQL → Should rank Core/OSS highly
|
||||
* - [ ] Paid → Self-hosted → Recent → SQL → Should rank Enterprise highly
|
||||
* - [ ] Free → Cloud → Recent → Flux → Should rank Cloud Serverless/TSM
|
||||
* - [ ] Paid → Cloud → Recent → SQL → Should rank Dedicated highly
|
||||
* - [ ] Unknown license → Should not eliminate products
|
||||
*
|
||||
* Age-based Scoring:
|
||||
* - [ ] Recent (< 1 year) → Should favor v3 products
|
||||
* - [ ] 1-5 years → Should favor v2 era products
|
||||
* - [ ] 5+ years → Should favor v1 products only
|
||||
* - [ ] Unknown age → Should not affect scoring
|
||||
*
|
||||
* Language-based Elimination:
|
||||
* - [ ] SQL only → Should eliminate v1, v2, Cloud TSM
|
||||
* - [ ] Flux only → Should eliminate v1, all v3 products
|
||||
* - [ ] InfluxQL only → Should favor v1, but not eliminate others
|
||||
* - [ ] Multiple languages → Should not eliminate products
|
||||
* - [ ] Unknown language → Should not affect scoring
|
||||
*
|
||||
* Combined Detection Scenarios:
|
||||
* -----------------------------
|
||||
* URL + Questionnaire:
|
||||
* - [ ] Port 8181 + Free license → Should show Core as high confidence
|
||||
* - [ ] Port 8181 + Paid license → Should show Enterprise as high confidence
|
||||
* - [ ] Port 8086 + Free + Recent + SQL → Mixed signals, show ranked results
|
||||
* - [ ] Cloud URL pattern + Paid → Should favor Dedicated/Serverless
|
||||
*
|
||||
* UI/UX Scenarios:
|
||||
* ----------------
|
||||
* Navigation:
|
||||
* - [ ] Back button: From URL input → Should return to "URL known" question
|
||||
* - [ ] Back button: From questionnaire Q2 → Should return to Q1
|
||||
* - [ ] Back button: From first question → Should stay at first question
|
||||
* - [ ] Progress bar: Should update with each question
|
||||
*
|
||||
* Results Display:
|
||||
* - [ ] High confidence (score > 60): Should show "Most Likely" label
|
||||
* - [ ] Medium confidence (30-60): Should show confidence rating
|
||||
* - [ ] Low confidence (< 30): Should show multiple candidates
|
||||
* - [ ] Score gap ≥ 15: Top result should stand out
|
||||
* - [ ] Score gap < 15: Should show multiple options
|
||||
*
|
||||
* Interactive Elements:
|
||||
* - [ ] Start questionnaire button: From detection results → Should hide results and start questions
|
||||
* - [ ] Restart button: Should clear all answers and return to start
|
||||
* - [ ] Grafana links: Should display for detected products
|
||||
* - [ ] Configuration guidance: Should display for top results
|
||||
* - [ ] Quick reference table: Should expand/collapse
|
||||
*
|
||||
* Pre-filled Values:
|
||||
* - [ ] Stored URL: Should pre-fill URL input from localStorage
|
||||
* - [ ] URL indicator: Should show when URL is pre-filled
|
||||
* - [ ] Clear indicator: Should hide when user edits URL
|
||||
*
|
||||
* Analytics Tracking Scenarios:
|
||||
* -----------------------------
|
||||
* - [ ] Modal opened: Track when component initializes
|
||||
* - [ ] Question answered: Track each answer with question_id and value
|
||||
* - [ ] URL detection: Track with detection_method: "url_analysis"
|
||||
* - [ ] Product detected: Track with detected_product and completion_status
|
||||
* - [ ] Restart: Track restart action
|
||||
*
|
||||
* Accessibility Scenarios:
|
||||
* ------------------------
|
||||
* - [ ] Keyboard navigation: Tab through buttons and inputs
|
||||
* - [ ] Focus management: Should focus on heading after showing result
|
||||
* - [ ] Screen reader: Labels and ARIA attributes present
|
||||
* - [ ] Color contrast: Results visible in different themes
|
||||
*
|
||||
* Error Handling:
|
||||
* ---------------
|
||||
* - [ ] Missing products data: Component should handle gracefully
|
||||
* - [ ] Missing influxdb_urls data: Should use fallback values
|
||||
* - [ ] Invalid JSON in data attributes: Should log warning and continue
|
||||
*
|
||||
* Edge Cases:
|
||||
* -----------
|
||||
* - [ ] Modal initialization: Component in modal should wait for modal to open
|
||||
* - [ ] Multiple instances: Each instance should work independently
|
||||
* - [ ] Page navigation: State should persist if using back button
|
||||
* - [ ] URL query params: Should update with detection results
|
||||
*/
|
||||
|
||||
const modalTriggerSelector = 'a.btn.influxdb-detector-trigger';
|
||||
|
||||
describe('InfluxDB Version Detector Component', function () {
|
||||
// Remove the global beforeEach to optimize for efficient running
|
||||
// Each describe block will visit the page once
|
||||
|
||||
describe('Component Data Attributes', function () {
|
||||
beforeEach(() => {
|
||||
cy.visit('/test-version-detector/');
|
||||
// The trigger is an anchor element with .btn class, not a button
|
||||
cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click();
|
||||
});
|
||||
|
||||
it('should not throw JavaScript console errors', function () {
|
||||
cy.window().then((win) => {
|
||||
const logs = [];
|
||||
const originalError = win.console.error;
|
||||
|
||||
win.console.error = (...args) => {
|
||||
logs.push(args.join(' '));
|
||||
originalError.apply(win.console, args);
|
||||
};
|
||||
|
||||
cy.wait(2000);
|
||||
|
||||
cy.then(() => {
|
||||
const relevantErrors = logs.filter(
|
||||
(log) =>
|
||||
log.includes('influxdb-version-detector') ||
|
||||
log.includes('detectContext is not a function') ||
|
||||
log.includes('Failed to parse influxdb_urls data')
|
||||
);
|
||||
expect(relevantErrors).to.have.length(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('URL with port 8086', function () {
|
||||
before(() => {
|
||||
cy.visit('/test-version-detector/');
|
||||
cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click();
|
||||
cy.get('[data-component="influxdb-version-detector"]')
|
||||
.eq(0)
|
||||
.within(() => {
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
it('should suggest legacy editions for custom URL or hostname', function () {
|
||||
cy.get('#url-input', { timeout: 10000 })
|
||||
.clear()
|
||||
.type('http://willieshotchicken.com:8086');
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
cy.get('.result')
|
||||
.invoke('text')
|
||||
.then((text) => {
|
||||
// Should mention multiple products for port 8086
|
||||
const mentionsLegacyEditions =
|
||||
text.includes('OSS 1.x') ||
|
||||
text.includes('OSS 2.x') ||
|
||||
text.includes('Enterprise');
|
||||
expect(mentionsLegacyEditions).to.be.true;
|
||||
});
|
||||
cy.get('#url-input', { timeout: 10000 })
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type('willieshotchicken.com:8086');
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
cy.get('.result')
|
||||
.invoke('text')
|
||||
.then((text) => {
|
||||
// Should mention multiple products
|
||||
const mentionsLegacyEditions =
|
||||
text.includes('OSS 1.x') ||
|
||||
text.includes('OSS 2.x') ||
|
||||
text.includes('Enterprise');
|
||||
expect(mentionsLegacyEditions).to.be.true;
|
||||
});
|
||||
});
|
||||
it('should suggest OSS for localhost', function () {
|
||||
cy.get('#url-input', { timeout: 10000 })
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type('http://localhost:8086');
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
cy.get('.result')
|
||||
.invoke('text')
|
||||
.then((text) => {
|
||||
// Should mention multiple editions
|
||||
const mentionsLegacyOSS =
|
||||
text.includes('OSS 1.x') || text.includes('OSS 2.x');
|
||||
expect(mentionsLegacyOSS).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('URL with port 8181', function () {
|
||||
const port8181UrlTests = [
|
||||
// InfluxDB 3 Core/Enterprise URLs
|
||||
{
|
||||
url: 'http://localhost:8181',
|
||||
},
|
||||
{
|
||||
url: 'https://my-server.com:8181',
|
||||
},
|
||||
];
|
||||
port8181UrlTests.forEach(({ url }) => {
|
||||
it(`should detect Core and Enterprise 3 for ${url}`, function () {
|
||||
cy.visit('/test-version-detector/');
|
||||
cy.get('body').then(($body) => {
|
||||
cy.get('#influxdb-url').clear().type(url);
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.result')
|
||||
.invoke('text')
|
||||
.then((text) => {
|
||||
// Should mention multiple editions
|
||||
const mentionsCoreAndEnterprise =
|
||||
text.includes('InfluxDB 3 Core') &&
|
||||
text.includes('InfluxDB 3 Enterprise');
|
||||
expect(mentionsCoreAndEnterprise).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('Cloud URLs', function () {
|
||||
const cloudUrlTests = [
|
||||
{
|
||||
url: 'https://us-west-2-1.aws.cloud2.influxdata.com',
|
||||
expectedText: 'Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://us-east-1-1.aws.cloud2.influxdata.com',
|
||||
expectedText: 'Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://eu-central-1-1.aws.cloud2.influxdata.com',
|
||||
expectedText: 'Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://us-central1-1.gcp.cloud2.influxdata.com',
|
||||
expectedText: 'Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://westeurope-1.azure.cloud2.influxdata.com',
|
||||
expectedText: 'Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://eastus-1.azure.cloud2.influxdata.com',
|
||||
expectedText: 'Cloud',
|
||||
},
|
||||
];
|
||||
|
||||
cloudUrlTests.forEach(({ url, expectedText }) => {
|
||||
it(`should detect ${expectedText} for ${url}`, function () {
|
||||
cy.visit('/test-version-detector/');
|
||||
cy.get('body').then(($body) => {
|
||||
cy.get('#influxdb-url').clear().type(url);
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
cy.get('.result').should('be.visible').and('contain', expectedText);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('Cloud Dedicated and Clustered URLs', function () {
|
||||
const clusterUrlTests = [
|
||||
// v3 Cloud Dedicated
|
||||
{
|
||||
url: 'https://cluster-id.a.influxdb.io',
|
||||
expectedText: 'Cloud Dedicated',
|
||||
},
|
||||
{
|
||||
url: 'https://my-cluster.a.influxdb.io',
|
||||
expectedText: 'Cloud Dedicated',
|
||||
},
|
||||
|
||||
// v1 Enterprise/v3 Clustered
|
||||
{ url: 'https://cluster-host.com', expectedText: 'Clustered' },
|
||||
];
|
||||
clusterUrlTests.forEach(({ url, expectedText }) => {
|
||||
it(`should detect ${expectedText} for ${url}`, function () {
|
||||
cy.visit('/test-version-detector/');
|
||||
cy.get('body').then(($body) => {
|
||||
cy.get('#influxdb-url').clear().type(url);
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
cy.get('.result').should('be.visible').and('contain', expectedText);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('Cloud Dedicated and Clustered URLs', function () {
|
||||
const clusterUrlTests = [
|
||||
// v3 Cloud Dedicated
|
||||
{
|
||||
url: 'https://cluster-id.a.influxdb.io',
|
||||
expectedText: 'Cloud Dedicated',
|
||||
},
|
||||
{
|
||||
url: 'https://my-cluster.a.influxdb.io',
|
||||
expectedText: 'Cloud Dedicated',
|
||||
},
|
||||
|
||||
// v1 Enterprise/v3 Clustered
|
||||
{ url: 'https://cluster-host.com', expectedText: 'Clustered' },
|
||||
];
|
||||
clusterUrlTests.forEach(({ url, expectedText }) => {
|
||||
it(`should detect ${expectedText} for ${url}`, function () {
|
||||
cy.visit('/test-version-detector/');
|
||||
cy.get('body').then(($body) => {
|
||||
cy.get('#influxdb-url').clear().type(url);
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
cy.get('.result').should('be.visible').and('contain', expectedText);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle cloud context detection', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
// Wait for URL input question to appear and then enter cloud context
|
||||
cy.get('#q-url-input', { timeout: 10000 }).should('be.visible');
|
||||
cy.get('#url-input', { timeout: 10000 })
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type('cloud 2');
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
// Should proceed to next step - either show result or start questionnaire
|
||||
// Don't be too specific about what happens next, just verify it progresses
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.find('.result').length > 0) {
|
||||
cy.get('.result').should('be.visible');
|
||||
} else {
|
||||
cy.get('.question.active', { timeout: 15000 }).should('be.visible');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle v3 port detection', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
// Wait for URL input question to appear and then test v3 port detection (8181)
|
||||
cy.get('#q-url-input', { timeout: 10000 }).should('be.visible');
|
||||
cy.get('#url-input', { timeout: 10000 })
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type('http://localhost:8181');
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
// Should progress to either result or questionnaire
|
||||
cy.get('body', { timeout: 15000 }).then(($body) => {
|
||||
if ($body.find('.result').length > 0) {
|
||||
cy.get('.result').should('be.visible');
|
||||
} else {
|
||||
cy.get('.question.active').should('be.visible');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('Questionnaire Flow', function () {
|
||||
beforeEach(() => {
|
||||
cy.visit('/test-version-detector/');
|
||||
// The trigger is an anchor element with .btn class, not a button
|
||||
cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click();
|
||||
});
|
||||
it('should start questionnaire for unknown URL', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
cy.get('#url-input').clear().type('https://unknown-server.com:9999');
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
cy.get('.question.active').should('be.visible');
|
||||
cy.get('.option-button').should('have.length.greaterThan', 0);
|
||||
});
|
||||
|
||||
it('should complete basic questionnaire flow', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
// Start questionnaire
|
||||
cy.get('#url-input')
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type('https://test.com');
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active', { timeout: 10000 }).should('be.visible');
|
||||
|
||||
// Answer questions with proper waiting for DOM updates
|
||||
const answers = ['Self-hosted', 'Free', '2-5 years', 'SQL'];
|
||||
|
||||
answers.forEach((answer, index) => {
|
||||
cy.get('.question.active', { timeout: 10000 }).should('be.visible');
|
||||
cy.get('.back-button').should('be.visible');
|
||||
cy.get('.option-button').contains(answer).should('be.visible').click();
|
||||
|
||||
// Wait for the next question or final result
|
||||
if (index < answers.length - 1) {
|
||||
cy.get('.question.active', { timeout: 5000 }).should('be.visible');
|
||||
}
|
||||
});
|
||||
|
||||
// Should show results
|
||||
cy.get('.result', { timeout: 10000 }).should('be.visible');
|
||||
});
|
||||
|
||||
it('should show all products when answering "I\'m not sure" to all questions', function () {
|
||||
// Test fix for: Core/Enterprise disappearing with all "unknown" answers
|
||||
cy.get('.option-button').contains("No, I don't know the URL").click();
|
||||
cy.get('.question.active', { timeout: 10000 }).should('be.visible');
|
||||
|
||||
// Answer "I'm not sure" to all questions
|
||||
for (let i = 0; i < 4; i++) {
|
||||
cy.get('.question.active', { timeout: 10000 }).should('be.visible');
|
||||
cy.get('.option-button').contains("I'm not sure").click();
|
||||
cy.wait(500);
|
||||
}
|
||||
|
||||
cy.get('.result', { timeout: 10000 }).should('be.visible');
|
||||
// Should show multiple products, not empty or filtered list
|
||||
cy.get('.result').invoke('text').should('have.length.greaterThan', 100);
|
||||
});
|
||||
|
||||
it('should NOT recommend InfluxDB 3 for Flux users (regression test)', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
cy.get('#url-input').should('be.visible').clear().type('cloud 2');
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active', { timeout: 10000 }).should('be.visible');
|
||||
|
||||
// Complete problematic scenario that was fixed
|
||||
const answers = ['Paid', '2-5 years', 'Flux'];
|
||||
answers.forEach((answer, index) => {
|
||||
cy.get('.question.active', { timeout: 10000 }).should('be.visible');
|
||||
cy.get('.option-button').contains(answer).should('be.visible').click();
|
||||
|
||||
// Wait for the next question or final result
|
||||
if (index < answers.length - 1) {
|
||||
cy.get('.question.active', { timeout: 5000 }).should('be.visible');
|
||||
}
|
||||
});
|
||||
|
||||
cy.get('.result', { timeout: 10000 }).should('be.visible');
|
||||
|
||||
// Should NOT recommend InfluxDB 3 products for Flux
|
||||
cy.get('.result').should('not.contain', 'InfluxDB 3 Core');
|
||||
cy.get('.result').should('not.contain', 'InfluxDB 3 Enterprise');
|
||||
});
|
||||
|
||||
// Comprehensive questionnaire scenarios covering all decision tree paths
|
||||
const questionnaireScenarios = [
|
||||
{
|
||||
name: 'SQL Filtering Test - Only InfluxDB 3 products for SQL (Free)',
|
||||
answers: ['Self-hosted', 'Free', 'Less than 6 months', 'SQL'],
|
||||
shouldContain: ['InfluxDB 3'],
|
||||
shouldNotContain: [
|
||||
'InfluxDB OSS 1.x',
|
||||
'InfluxDB OSS 2.x',
|
||||
'InfluxDB Enterprise v1.x',
|
||||
'InfluxDB Cloud (TSM)',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'SQL Filtering Test - Only InfluxDB 3 products for SQL (Paid)',
|
||||
answers: ['Self-hosted', 'Paid', 'Less than 6 months', 'SQL'],
|
||||
shouldContain: ['InfluxDB 3'],
|
||||
shouldNotContain: [
|
||||
'InfluxDB OSS 1.x',
|
||||
'InfluxDB OSS 2.x',
|
||||
'InfluxDB Enterprise v1.x',
|
||||
'InfluxDB Cloud (TSM)',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'SQL Filtering Test - Only InfluxDB 3 Cloud products for SQL',
|
||||
answers: [
|
||||
'Cloud (managed service)',
|
||||
'Paid',
|
||||
'Less than 6 months',
|
||||
'SQL',
|
||||
],
|
||||
shouldContain: ['Cloud'],
|
||||
shouldNotContain: [
|
||||
'InfluxDB OSS',
|
||||
'InfluxDB Enterprise v1.x',
|
||||
'InfluxDB Cloud (TSM)',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'OSS Free User - SQL (recent)',
|
||||
answers: ['Self-hosted', 'Free', 'Less than 6 months', 'SQL'],
|
||||
shouldContain: ['InfluxDB 3 Core'],
|
||||
shouldNotContain: ['InfluxDB 3 Enterprise'],
|
||||
},
|
||||
{
|
||||
name: 'OSS Free User - SQL (experienced)',
|
||||
answers: ['Self-hosted', 'Free', '2-5 years', 'SQL'],
|
||||
shouldContain: ['InfluxDB 3 Core'],
|
||||
shouldNotContain: ['InfluxDB 3 Enterprise'],
|
||||
},
|
||||
{
|
||||
name: 'Cloud Flux User',
|
||||
answers: [
|
||||
'Cloud (managed service)',
|
||||
'Paid',
|
||||
'Less than 6 months',
|
||||
'Flux',
|
||||
],
|
||||
shouldContain: ['InfluxDB v2', 'Cloud'],
|
||||
shouldNotContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'],
|
||||
},
|
||||
{
|
||||
name: 'Cloud SQL User (recent)',
|
||||
answers: [
|
||||
'Cloud (managed service)',
|
||||
'Paid',
|
||||
'Less than 6 months',
|
||||
'SQL',
|
||||
],
|
||||
shouldContain: ['Cloud Serverless', 'Cloud Dedicated'],
|
||||
shouldNotContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'],
|
||||
},
|
||||
{
|
||||
name: 'Modern Self-hosted SQL User',
|
||||
answers: ['Self-hosted', 'Paid', 'Less than 6 months', 'SQL'],
|
||||
shouldContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'],
|
||||
shouldNotContain: ['Cloud'],
|
||||
},
|
||||
{
|
||||
name: 'High Volume Enterprise User',
|
||||
answers: ['Self-hosted', 'Paid', 'Less than 6 months', 'SQL', 'Yes'],
|
||||
shouldContain: ['InfluxDB 3 Enterprise'],
|
||||
shouldNotContain: ['Cloud'],
|
||||
},
|
||||
{
|
||||
name: 'Legacy Self-hosted User (InfluxQL)',
|
||||
answers: ['Self-hosted', 'Free', '5+ years', 'InfluxQL'],
|
||||
shouldContain: ['InfluxDB v1', 'OSS'],
|
||||
shouldNotContain: ['InfluxDB 3'],
|
||||
},
|
||||
{
|
||||
name: 'Legacy Enterprise User',
|
||||
answers: ['Self-hosted', 'Paid', '5+ years', 'InfluxQL'],
|
||||
shouldContain: ['InfluxDB Enterprise', 'InfluxDB v1'],
|
||||
shouldNotContain: ['InfluxDB 3'],
|
||||
},
|
||||
{
|
||||
name: 'Experienced OSS User (Flux)',
|
||||
answers: ['Self-hosted', 'Free', '2-5 years', 'Flux'],
|
||||
shouldContain: ['InfluxDB v2', 'OSS'],
|
||||
shouldNotContain: ['InfluxDB 3', 'Enterprise'],
|
||||
},
|
||||
{
|
||||
name: 'Cloud Free User (recent)',
|
||||
answers: [
|
||||
'Cloud (managed service)',
|
||||
'Free',
|
||||
'Less than 6 months',
|
||||
'SQL',
|
||||
],
|
||||
shouldContain: ['Cloud Serverless'],
|
||||
shouldNotContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'],
|
||||
},
|
||||
{
|
||||
name: 'SQL Cloud User - Only InfluxDB 3 Cloud products',
|
||||
answers: [
|
||||
'Cloud (managed service)',
|
||||
'Paid',
|
||||
'Less than 6 months',
|
||||
'SQL',
|
||||
],
|
||||
shouldContain: ['Cloud Serverless', 'Cloud Dedicated'],
|
||||
shouldNotContain: [
|
||||
'InfluxDB OSS',
|
||||
'InfluxDB Enterprise v1',
|
||||
'InfluxDB Cloud (TSM)',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Uncertain User',
|
||||
answers: [
|
||||
"I'm not sure",
|
||||
"I'm not sure",
|
||||
"I'm not sure",
|
||||
"I'm not sure",
|
||||
],
|
||||
shouldContain: [], // Should still provide some recommendations
|
||||
shouldNotContain: [],
|
||||
},
|
||||
];
|
||||
|
||||
questionnaireScenarios.forEach((scenario) => {
|
||||
it(`should handle questionnaire scenario: ${scenario.name}`, function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
// Start questionnaire
|
||||
cy.get('#url-input').clear().type('https://unknown-server.com:9999');
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
|
||||
// Answer questions
|
||||
scenario.answers.forEach((answer) => {
|
||||
cy.get('.question.active').should('be.visible');
|
||||
cy.get('.option-button').contains(answer).click();
|
||||
cy.wait(500);
|
||||
});
|
||||
|
||||
// Verify results
|
||||
cy.get('.result').should('be.visible');
|
||||
|
||||
// Check expected content
|
||||
scenario.shouldContain.forEach((product) => {
|
||||
cy.get('.result').should('contain', product);
|
||||
});
|
||||
|
||||
// Check content that should NOT be present
|
||||
scenario.shouldNotContain.forEach((product) => {
|
||||
cy.get('.result').should('not.contain', product);
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT recommend InfluxDB 3 for 5+ year installations (time-aware)', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
cy.get('#url-input').clear().type('https://unknown-server.com:9999');
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
|
||||
// Test that v3 products are excluded for 5+ years
|
||||
const answers = ['Free', 'Self-hosted', 'More than 5 years', 'SQL'];
|
||||
answers.forEach((answer) => {
|
||||
cy.get('.question.active').should('be.visible');
|
||||
cy.get('.option-button').contains(answer).click();
|
||||
cy.wait(500);
|
||||
});
|
||||
|
||||
cy.get('.result').should('be.visible');
|
||||
cy.get('.result').should('not.contain', 'InfluxDB 3 Core');
|
||||
cy.get('.result').should('not.contain', 'InfluxDB 3 Enterprise');
|
||||
// Should recommend legacy products instead
|
||||
cy.get('.result').should('contain', 'InfluxDB');
|
||||
});
|
||||
});
|
||||
|
||||
it('should apply -100 Flux penalty to InfluxDB 3 products', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
cy.get('#url-input').clear().type('https://unknown-server.com:9999');
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
|
||||
// Even for recent, paid, self-hosted users, Flux should eliminate v3 products
|
||||
const answers = ['Self-hosted', 'Paid', 'Less than 6 months', 'Flux'];
|
||||
answers.forEach((answer) => {
|
||||
cy.get('.question.active').should('be.visible');
|
||||
cy.get('.option-button').contains(answer).click();
|
||||
cy.wait(500);
|
||||
});
|
||||
|
||||
cy.get('.result').should('be.visible');
|
||||
cy.get('.result').should('not.contain', 'InfluxDB 3 Core');
|
||||
cy.get('.result').should('not.contain', 'InfluxDB 3 Enterprise');
|
||||
});
|
||||
|
||||
it('should detect cloud context correctly with regex patterns', function () {
|
||||
const cloudPatterns = ['cloud 2', 'cloud v2', 'influxdb cloud 2'];
|
||||
|
||||
// Test first pattern in current session
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
cy.get('#url-input').clear().type(cloudPatterns[0]);
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
});
|
||||
|
||||
// Navigation and interaction tests
|
||||
it('should allow going back through questionnaire questions', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
// Start questionnaire
|
||||
cy.get('#url-input').clear().type('https://unknown-server.com:9999');
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
|
||||
// Answer first question
|
||||
cy.get('.option-button').first().click();
|
||||
cy.wait(500);
|
||||
|
||||
// Check if back button exists and is clickable
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.find('.back-button').length > 0) {
|
||||
cy.get('.back-button').should('be.visible').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow restarting questionnaire from results', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
// Complete a questionnaire
|
||||
cy.get('#url-input').clear().type('https://unknown-server.com:9999');
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
|
||||
const answers = ['Self-hosted', 'Free', '2-5 years', 'SQL'];
|
||||
answers.forEach((answer) => {
|
||||
cy.get('.question.active').should('be.visible');
|
||||
cy.get('.back-button').should('be.visible');
|
||||
cy.get('.option-button').contains(answer).click();
|
||||
cy.wait(500);
|
||||
});
|
||||
|
||||
cy.get('.result').should('be.visible');
|
||||
|
||||
// Check if restart button exists and works
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.find('.restart-button').length > 0) {
|
||||
cy.get('.restart-button').should('be.visible').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('Basic Error Handling', function () {
|
||||
beforeEach(() => {
|
||||
cy.visit('/test-version-detector/');
|
||||
// The trigger is an anchor element with .btn class, not a button
|
||||
cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click();
|
||||
});
|
||||
|
||||
it('should handle empty URL input gracefully', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
cy.get('#url-input').clear();
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
// Should start questionnaire or show guidance
|
||||
cy.get('.question.active, .result').should('be.visible');
|
||||
});
|
||||
|
||||
it('should handle invalid URL format gracefully', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
cy.get('#url-input').clear().type('not-a-valid-url');
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
// Should handle gracefully
|
||||
cy.get('.question.active, .result').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('SQL Language Filtering', function () {
|
||||
beforeEach(() => {
|
||||
cy.visit('/test-version-detector/');
|
||||
// The trigger is an anchor element with .btn class, not a button
|
||||
cy.contains(modalTriggerSelector, 'Detect my InfluxDB version').click();
|
||||
});
|
||||
|
||||
it('should only show InfluxDB 3 products when SQL is selected', function () {
|
||||
// Click "Yes, I know the URL" first
|
||||
cy.get('.option-button').contains('Yes, I know the URL').click();
|
||||
|
||||
// Start questionnaire with unknown URL
|
||||
cy.get('#url-input').clear().type('https://unknown-server.com:9999');
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
|
||||
// Answer questions leading to SQL selection
|
||||
const answers = ['Self-hosted', 'Free', 'Less than 6 months', 'SQL'];
|
||||
answers.forEach((answer) => {
|
||||
cy.get('.question.active').should('be.visible');
|
||||
cy.get('.option-button').contains(answer).click();
|
||||
cy.wait(500);
|
||||
});
|
||||
|
||||
cy.get('.result').should('be.visible');
|
||||
|
||||
// Get the full result text to verify filtering
|
||||
cy.get('.result')
|
||||
.invoke('text')
|
||||
.then((resultText) => {
|
||||
// Verify that ONLY InfluxDB 3 products are shown
|
||||
const shouldNotContain = [
|
||||
'InfluxDB Enterprise v1.x',
|
||||
'InfluxDB OSS v2.x',
|
||||
'InfluxDB OSS 1.x',
|
||||
'InfluxDB Cloud (TSM)',
|
||||
];
|
||||
|
||||
// Check that forbidden products are NOT in results
|
||||
shouldNotContain.forEach((forbiddenProduct) => {
|
||||
expect(resultText).to.not.contain(forbiddenProduct);
|
||||
});
|
||||
|
||||
// Verify at least one InfluxDB 3 product is shown
|
||||
const hasValidProduct =
|
||||
resultText.includes('InfluxDB 3 Core') ||
|
||||
resultText.includes('Cloud Dedicated') ||
|
||||
resultText.includes('Cloud Serverless') ||
|
||||
resultText.includes('InfluxDB Clustered');
|
||||
|
||||
expect(hasValidProduct).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -22,4 +22,7 @@
|
|||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
|
||||
// Import custom commands for InfluxDB Version Detector
|
||||
import './influxdb-version-detector-commands.js';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,299 @@
|
|||
// Custom Cypress commands for InfluxDB Version Detector testing
|
||||
|
||||
/**
|
||||
* Navigate to a page with the version detector component
|
||||
* @param {string} [path='/influxdb3/core/visualize-data/grafana/'] - Path to a page with the component
|
||||
*/
|
||||
Cypress.Commands.add(
|
||||
'visitVersionDetector',
|
||||
(path = '/influxdb3/core/visualize-data/grafana/') => {
|
||||
cy.visit(path);
|
||||
cy.get('[data-component="influxdb-version-detector"]', {
|
||||
timeout: 10000,
|
||||
}).should('be.visible');
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test URL detection for a specific URL
|
||||
* @param {string} url - The URL to test
|
||||
* @param {string} expectedProduct - Expected product name in the result
|
||||
*/
|
||||
Cypress.Commands.add('testUrlDetection', (url, expectedProduct) => {
|
||||
cy.get('#influxdb-url').clear().type(url);
|
||||
cy.get('.submit-button').click();
|
||||
|
||||
cy.get('.result.show', { timeout: 5000 }).should('be.visible');
|
||||
cy.get('.detected-version').should('contain', expectedProduct);
|
||||
});
|
||||
|
||||
/**
|
||||
* Complete a questionnaire with given answers
|
||||
* @param {string[]} answers - Array of answers to select in order
|
||||
*/
|
||||
Cypress.Commands.add('completeQuestionnaire', (answers) => {
|
||||
answers.forEach((answer, index) => {
|
||||
cy.get('.question.active', { timeout: 3000 }).should('be.visible');
|
||||
cy.get('.option-button').contains(answer).should('be.visible').click();
|
||||
|
||||
// Wait for transition between questions
|
||||
if (index < answers.length - 1) {
|
||||
cy.wait(500);
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for final results
|
||||
cy.get('.result.show', { timeout: 5000 }).should('be.visible');
|
||||
});
|
||||
|
||||
/**
|
||||
* Start questionnaire with unknown URL
|
||||
* @param {string} [url='https://unknown-server.com:9999'] - URL to trigger questionnaire
|
||||
*/
|
||||
Cypress.Commands.add(
|
||||
'startQuestionnaire',
|
||||
(url = 'https://unknown-server.com:9999') => {
|
||||
cy.get('#influxdb-url').clear().type(url);
|
||||
cy.get('.submit-button').click();
|
||||
cy.get('.question.active', { timeout: 5000 }).should('be.visible');
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Verify questionnaire results contain/don't contain specific products
|
||||
* @param {Object} options - Configuration object
|
||||
* @param {string[]} [options.shouldContain] - Products that should be in results
|
||||
* @param {string[]} [options.shouldNotContain] - Products that should NOT be in results
|
||||
*/
|
||||
Cypress.Commands.add(
|
||||
'verifyQuestionnaireResults',
|
||||
({ shouldContain = [], shouldNotContain = [] }) => {
|
||||
cy.get('.result.show', { timeout: 5000 }).should('be.visible');
|
||||
|
||||
shouldContain.forEach((product) => {
|
||||
cy.get('.result').should('contain', product);
|
||||
});
|
||||
|
||||
shouldNotContain.forEach((product) => {
|
||||
cy.get('.result').should('not.contain', product);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test navigation through questionnaire (back/restart functionality)
|
||||
*/
|
||||
Cypress.Commands.add('testQuestionnaireNavigation', () => {
|
||||
// Answer first question
|
||||
cy.get('.option-button').first().click();
|
||||
cy.wait(500);
|
||||
|
||||
// Test back button
|
||||
cy.get('.back-button').should('be.visible').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
cy.get('.progress .progress-bar').should('have.css', 'width', '0px');
|
||||
|
||||
// Complete questionnaire to test restart
|
||||
const quickAnswers = ['Self-hosted', 'Free', '2-5 years', 'SQL'];
|
||||
cy.completeQuestionnaire(quickAnswers);
|
||||
|
||||
// Test restart button
|
||||
cy.get('.restart-button', { timeout: 3000 }).should('be.visible').click();
|
||||
cy.get('.question.active').should('be.visible');
|
||||
cy.get('.progress .progress-bar').should('have.css', 'width', '0px');
|
||||
});
|
||||
|
||||
/**
|
||||
* Check for JavaScript console errors related to the component
|
||||
*/
|
||||
Cypress.Commands.add('checkForConsoleErrors', () => {
|
||||
cy.window().then((win) => {
|
||||
const logs = [];
|
||||
const originalConsoleError = win.console.error;
|
||||
|
||||
win.console.error = (...args) => {
|
||||
logs.push(args.join(' '));
|
||||
originalConsoleError.apply(win.console, args);
|
||||
};
|
||||
|
||||
// Wait for any potential errors to surface
|
||||
cy.wait(1000);
|
||||
|
||||
cy.then(() => {
|
||||
const relevantErrors = logs.filter(
|
||||
(log) =>
|
||||
log.includes('influxdb-version-detector') ||
|
||||
log.includes('Failed to parse influxdb_urls data') ||
|
||||
log.includes('SyntaxError') ||
|
||||
log.includes('#ZgotmplZ') ||
|
||||
log.includes('detectContext is not a function')
|
||||
);
|
||||
|
||||
if (relevantErrors.length > 0) {
|
||||
throw new Error(
|
||||
`Console errors detected: ${relevantErrors.join('; ')}`
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Test URL scenarios from the influxdb_urls.yml data
|
||||
*/
|
||||
Cypress.Commands.add('testAllKnownUrls', () => {
|
||||
const urlTestCases = [
|
||||
// OSS URLs
|
||||
{ url: 'http://localhost:8086', product: 'InfluxDB OSS' },
|
||||
{ url: 'https://my-server.com:8086', product: 'InfluxDB OSS' },
|
||||
|
||||
// InfluxDB 3 URLs
|
||||
{ url: 'http://localhost:8181', product: 'InfluxDB 3' },
|
||||
{ url: 'https://my-server.com:8181', product: 'InfluxDB 3' },
|
||||
|
||||
// Cloud URLs
|
||||
{
|
||||
url: 'https://us-west-2-1.aws.cloud2.influxdata.com',
|
||||
product: 'InfluxDB Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://us-east-1-1.aws.cloud2.influxdata.com',
|
||||
product: 'InfluxDB Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://eu-central-1-1.aws.cloud2.influxdata.com',
|
||||
product: 'InfluxDB Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://us-central1-1.gcp.cloud2.influxdata.com',
|
||||
product: 'InfluxDB Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://westeurope-1.azure.cloud2.influxdata.com',
|
||||
product: 'InfluxDB Cloud',
|
||||
},
|
||||
{
|
||||
url: 'https://eastus-1.azure.cloud2.influxdata.com',
|
||||
product: 'InfluxDB Cloud',
|
||||
},
|
||||
|
||||
// Cloud Dedicated
|
||||
{
|
||||
url: 'https://cluster-id.a.influxdb.io',
|
||||
product: 'InfluxDB Cloud Dedicated',
|
||||
},
|
||||
{
|
||||
url: 'https://my-cluster.a.influxdb.io',
|
||||
product: 'InfluxDB Cloud Dedicated',
|
||||
},
|
||||
|
||||
// Clustered
|
||||
{ url: 'https://cluster-host.com', product: 'InfluxDB Clustered' },
|
||||
];
|
||||
|
||||
urlTestCases.forEach(({ url, product }) => {
|
||||
cy.visitVersionDetector();
|
||||
cy.testUrlDetection(url, product);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Test comprehensive questionnaire scenarios
|
||||
*/
|
||||
Cypress.Commands.add('testQuestionnaireScenarios', () => {
|
||||
const scenarios = [
|
||||
{
|
||||
name: 'OSS Free User',
|
||||
answers: ['Self-hosted', 'Free', '2-5 years', 'SQL'],
|
||||
shouldContain: ['InfluxDB OSS', 'InfluxDB v2'],
|
||||
shouldNotContain: ['InfluxDB 3 Enterprise'],
|
||||
},
|
||||
{
|
||||
name: 'Cloud Flux User',
|
||||
answers: [
|
||||
'Cloud (managed service)',
|
||||
'Paid',
|
||||
'Less than 6 months',
|
||||
'Flux',
|
||||
],
|
||||
shouldContain: ['InfluxDB v2'],
|
||||
shouldNotContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'],
|
||||
},
|
||||
{
|
||||
name: 'Modern Self-hosted SQL User',
|
||||
answers: ['Self-hosted', 'Paid', 'Less than 6 months', 'SQL'],
|
||||
shouldContain: ['InfluxDB 3 Core', 'InfluxDB 3 Enterprise'],
|
||||
shouldNotContain: [],
|
||||
},
|
||||
{
|
||||
name: 'High Volume Enterprise User',
|
||||
answers: ['Self-hosted', 'Paid', 'Less than 6 months', 'SQL', 'Yes'],
|
||||
shouldContain: ['InfluxDB 3 Enterprise'],
|
||||
shouldNotContain: [],
|
||||
},
|
||||
{
|
||||
name: 'Uncertain User',
|
||||
answers: ["I'm not sure", "I'm not sure", "I'm not sure", "I'm not sure"],
|
||||
shouldContain: [], // Should still provide some recommendations
|
||||
shouldNotContain: [],
|
||||
},
|
||||
];
|
||||
|
||||
scenarios.forEach((scenario) => {
|
||||
cy.visitVersionDetector();
|
||||
cy.startQuestionnaire();
|
||||
cy.completeQuestionnaire(scenario.answers);
|
||||
cy.verifyQuestionnaireResults({
|
||||
shouldContain: scenario.shouldContain,
|
||||
shouldNotContain: scenario.shouldNotContain,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Test accessibility features
|
||||
*/
|
||||
Cypress.Commands.add('testAccessibility', () => {
|
||||
// Test keyboard navigation
|
||||
cy.get('body').tab();
|
||||
cy.focused().should('have.id', 'influxdb-url');
|
||||
|
||||
cy.focused().type('https://test.com');
|
||||
cy.focused().tab();
|
||||
cy.focused().should('have.class', 'submit-button');
|
||||
|
||||
cy.focused().type('{enter}');
|
||||
cy.get('.question.active', { timeout: 3000 }).should('be.visible');
|
||||
|
||||
// Test that buttons are focusable
|
||||
cy.get('.option-button')
|
||||
.first()
|
||||
.should('be.visible')
|
||||
.focus()
|
||||
.should('be.focused');
|
||||
});
|
||||
|
||||
/**
|
||||
* Test theme integration
|
||||
*/
|
||||
Cypress.Commands.add('testThemeIntegration', () => {
|
||||
// Test light theme (default)
|
||||
cy.get('[data-component="influxdb-version-detector"]')
|
||||
.should('have.css', 'background-color')
|
||||
.and('not.equal', 'transparent');
|
||||
|
||||
cy.get('.detector-title')
|
||||
.should('have.css', 'color')
|
||||
.and('not.equal', 'rgb(0, 0, 0)');
|
||||
|
||||
// Test dark theme if theme switcher exists
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.find('[data-theme-toggle]').length > 0) {
|
||||
cy.get('[data-theme-toggle]').click();
|
||||
|
||||
cy.get('[data-component="influxdb-version-detector"]')
|
||||
.should('have.css', 'background-color')
|
||||
.and('not.equal', 'rgb(255, 255, 255)');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -2,8 +2,7 @@
|
|||
* InfluxData Documentation E2E Test Runner
|
||||
*
|
||||
* This script automates running Cypress end-to-end tests for the InfluxData documentation site.
|
||||
* It handles starting a local Hugo server, mapping content files to their URLs, and running Cypress tests,
|
||||
* and reporting broken links.
|
||||
* It handles starting a local Hugo server, mapping content files to their URLs, and running Cypress tests.
|
||||
*
|
||||
* Usage: node run-e2e-specs.js [file paths...] [--spec test specs...]
|
||||
*/
|
||||
|
|
@ -303,7 +302,7 @@ async function main() {
|
|||
try {
|
||||
const screenshotsDir = path.resolve('cypress/screenshots');
|
||||
const videosDir = path.resolve('cypress/videos');
|
||||
const specScreenshotDir = path.join(screenshotsDir, 'article-links.cy.js');
|
||||
const specScreenshotDir = path.join(screenshotsDir, 'content');
|
||||
|
||||
// Ensure base directories exist
|
||||
ensureDirectoryExists(screenshotsDir);
|
||||
|
|
@ -402,7 +401,7 @@ async function main() {
|
|||
|
||||
if (testFailureCount > 0) {
|
||||
console.warn(
|
||||
`ℹ️ Note: ${testFailureCount} test(s) failed but no broken links were detected in the report.`
|
||||
`ℹ️ Note: ${testFailureCount} test(s) failed.`
|
||||
);
|
||||
|
||||
// Provide detailed failure analysis
|
||||
|
|
|
|||
|
|
@ -8,6 +8,20 @@ influxdb3_core:
|
|||
latest: core
|
||||
latest_patch: 3.5.0
|
||||
placeholder_host: localhost:8181
|
||||
detector_config:
|
||||
query_languages:
|
||||
SQL:
|
||||
required_params: ['Host', 'Database']
|
||||
optional_params: []
|
||||
InfluxQL:
|
||||
required_params: ['Host', 'Database']
|
||||
optional_params: []
|
||||
characteristics: ['Free', 'Self-hosted', 'SQL/InfluxQL', 'No auth required', 'Databases']
|
||||
detection:
|
||||
ping_headers:
|
||||
x-influxdb-version: '^3\.'
|
||||
x-influxdb-build: 'Core'
|
||||
url_contains: ['localhost:8181']
|
||||
ai_sample_questions:
|
||||
- How do I install and run InfluxDB 3 Core?
|
||||
- How do I write a plugin for the Python Processing engine?
|
||||
|
|
@ -23,6 +37,20 @@ influxdb3_enterprise:
|
|||
latest: enterprise
|
||||
latest_patch: 3.5.0
|
||||
placeholder_host: localhost:8181
|
||||
detector_config:
|
||||
query_languages:
|
||||
SQL:
|
||||
required_params: ['Host', 'Database', 'Token']
|
||||
optional_params: []
|
||||
InfluxQL:
|
||||
required_params: ['Host', 'Database', 'Token']
|
||||
optional_params: []
|
||||
characteristics: ['Paid', 'Self-hosted', 'SQL/InfluxQL', 'Token', 'Databases']
|
||||
detection:
|
||||
ping_headers:
|
||||
x-influxdb-version: '^3\.'
|
||||
x-influxdb-build: 'Enterprise'
|
||||
url_contains: ['localhost:8181']
|
||||
ai_sample_questions:
|
||||
- How do I install and run InfluxDB 3 Enterprise?
|
||||
- Help me write a plugin for the Python Processing engine?
|
||||
|
|
@ -51,6 +79,20 @@ influxdb3_cloud_serverless:
|
|||
list_order: 2
|
||||
latest: cloud-serverless
|
||||
placeholder_host: cloud2.influxdata.com
|
||||
detector_config:
|
||||
query_languages:
|
||||
SQL:
|
||||
required_params: ['Host', 'Bucket', 'Token']
|
||||
optional_params: []
|
||||
InfluxQL:
|
||||
required_params: ['Host', 'Bucket', 'Token']
|
||||
optional_params: []
|
||||
Flux:
|
||||
required_params: ['Host', 'Organization', 'Token', 'Default bucket']
|
||||
optional_params: []
|
||||
characteristics: ['Paid/Free', 'Cloud', 'All languages', 'Token', 'Buckets']
|
||||
detection:
|
||||
url_contains: ['us-east-1-1.aws.cloud2.influxdata.com', 'eu-central-1-1.aws.cloud2.influxdata.com']
|
||||
ai_sample_questions:
|
||||
- How do I migrate from InfluxDB Cloud 2 to InfluxDB Cloud Serverless?
|
||||
- What tools can I use to write data to InfluxDB Cloud Serverless?
|
||||
|
|
@ -66,6 +108,17 @@ influxdb3_cloud_dedicated:
|
|||
link: "https://www.influxdata.com/contact-sales-cloud-dedicated/"
|
||||
latest_cli: 2.10.5
|
||||
placeholder_host: cluster-id.a.influxdb.io
|
||||
detector_config:
|
||||
query_languages:
|
||||
SQL:
|
||||
required_params: ['Host', 'Database', 'Token']
|
||||
optional_params: []
|
||||
InfluxQL:
|
||||
required_params: ['Host', 'Database', 'Token']
|
||||
optional_params: []
|
||||
characteristics: ['Paid', 'Cloud', 'SQL/InfluxQL', 'Token', 'Databases']
|
||||
detection:
|
||||
url_contains: ['influxdb.io']
|
||||
ai_sample_questions:
|
||||
- How do I migrate from InfluxDB v1 to InfluxDB Cloud Dedicated?
|
||||
- What tools can I use to write data to Cloud Dedicated?
|
||||
|
|
@ -81,6 +134,18 @@ influxdb3_clustered:
|
|||
latest: clustered
|
||||
link: "https://www.influxdata.com/contact-sales-influxdb-clustered/"
|
||||
placeholder_host: cluster-host.com
|
||||
detector_config:
|
||||
query_languages:
|
||||
SQL:
|
||||
required_params: ['Host', 'Database', 'Token']
|
||||
optional_params: []
|
||||
InfluxQL:
|
||||
required_params: ['URL', 'Database', 'Token']
|
||||
optional_params: []
|
||||
characteristics: ['Paid', 'Self-hosted', 'SQL/InfluxQL', 'Token', 'Databases']
|
||||
detection:
|
||||
ping_headers:
|
||||
x-influxdb-version: 'influxqlbridged-development'
|
||||
ai_sample_questions:
|
||||
- How do I use a Helm chart to configure Clustered?
|
||||
- What tools can I use to write data to Clustered?
|
||||
|
|
@ -103,6 +168,20 @@ influxdb:
|
|||
v1: 1.12.2
|
||||
latest_cli:
|
||||
v2: 2.7.5
|
||||
detector_config:
|
||||
query_languages:
|
||||
InfluxQL:
|
||||
required_params: ['URL', 'Database', 'Auth Type (Basic or Token)']
|
||||
optional_params: []
|
||||
Flux:
|
||||
required_params: ['URL', 'Token', 'Default bucket']
|
||||
optional_params: []
|
||||
characteristics: ['Free', 'Self-hosted', 'InfluxQL/Flux', 'Token or Username/Password', 'Buckets']
|
||||
detection:
|
||||
ping_headers:
|
||||
x-influxdb-build: 'OSS'
|
||||
x-influxdb-version: '^(1|2)\.'
|
||||
url_contains: ['localhost:8086']
|
||||
ai_sample_questions:
|
||||
- How do I write and query data with InfluxDB v2 OSS?
|
||||
- How can I migrate from InfluxDB v2 OSS to InfluxDB 3 Core?
|
||||
|
|
@ -117,6 +196,17 @@ influxdb_cloud:
|
|||
list_order: 1
|
||||
latest: cloud
|
||||
placeholder_host: cloud2.influxdata.com
|
||||
detector_config:
|
||||
query_languages:
|
||||
InfluxQL:
|
||||
required_params: ['URL', 'Database', 'Token']
|
||||
optional_params: []
|
||||
Flux:
|
||||
required_params: ['URL', 'Organization', 'Token', 'Default bucket']
|
||||
optional_params: []
|
||||
characteristics: ['Paid/Free', 'Cloud', 'InfluxQL/Flux', 'Token', 'Databases/Buckets']
|
||||
detection:
|
||||
url_contains: ['us-west-2-1.aws.cloud2.influxdata.com', 'us-west-2-2.aws.cloud2.influxdata.com', 'us-east-1-1.aws.cloud2.influxdata.com', 'eu-central-1-1.aws.cloud2.influxdata.com', 'us-central1-1.gcp.cloud2.influxdata.com', 'westeurope-1.azure.cloud2.influxdata.com', 'eastus-1.azure.cloud2.influxdata.com']
|
||||
ai_sample_questions:
|
||||
- How do I write and query data with InfluxDB Cloud 2?
|
||||
- How is Cloud 2 different from Cloud Serverless?
|
||||
|
|
@ -186,6 +276,18 @@ enterprise_influxdb:
|
|||
latest: v1.12
|
||||
latest_patches:
|
||||
v1: 1.12.2
|
||||
detector_config:
|
||||
query_languages:
|
||||
InfluxQL:
|
||||
required_params: ['URL', 'Database', 'User', 'Password']
|
||||
optional_params: []
|
||||
Flux:
|
||||
required_params: ['URL', 'User', 'Password', 'Default database']
|
||||
optional_params: []
|
||||
characteristics: ['Paid', 'Self-hosted', 'InfluxQL/Flux', 'Username/Password', 'Databases']
|
||||
detection:
|
||||
ping_headers:
|
||||
x-influxdb-build: 'Enterprise'
|
||||
ai_sample_questions:
|
||||
- How can I configure my InfluxDB v1 Enterprise server?
|
||||
- How do I replicate data between InfluxDB v1 Enterprise and OSS?
|
||||
|
|
|
|||
|
|
@ -150,8 +150,19 @@ export default [
|
|||
},
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
languageOptions: {
|
||||
parser: tseslint.parser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// Rules specific to TypeScript files
|
||||
// TypeScript-specific rules
|
||||
'@typescript-eslint/no-unused-vars': 'warn',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'warn',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -160,6 +171,7 @@ export default [
|
|||
'**/node_modules/**',
|
||||
'**/public/**',
|
||||
'**/resources/**',
|
||||
'**/dist/**',
|
||||
'**/.hugo_build.lock',
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
<a id="modal-close"href="#"><span class="icon-remove"></span></a>
|
||||
<!-- Modal window content blocks-->
|
||||
{{ partial "footer/modals/influxdb-url.html" . }}
|
||||
{{ partial "footer/modals/influxdb-version-detector.html" . }}
|
||||
{{ partial "footer/modals/page-feedback.html" . }}
|
||||
{{ if or (.Page.HasShortcode "influxdb/custom-timestamps") (.Page.HasShortcode "influxdb/custom-timestamps-span") }}
|
||||
{{ partial "footer/modals/influxdb-gs-date-select.html" . }}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
{{/*
|
||||
InfluxDB Version Detector Modal Template
|
||||
|
||||
This modal contains the interactive version detector component that helps users
|
||||
identify which InfluxDB product they're using through a guided questionnaire.
|
||||
*/}}
|
||||
|
||||
{{/* Process products data into detector format */}}
|
||||
{{ $detectorProducts := dict }}
|
||||
{{ range $key, $product := site.Data.products }}
|
||||
{{ if $product.detector_config }}
|
||||
{{/* Include detector_config plus name and placeholder_host for configuration guidance */}}
|
||||
{{ $productData := $product.detector_config }}
|
||||
{{ if $product.name }}
|
||||
{{ $productData = merge $productData (dict "name" $product.name) }}
|
||||
{{ end }}
|
||||
{{ if $product.placeholder_host }}
|
||||
{{ $productData = merge $productData (dict "placeholder_host" $product.placeholder_host) }}
|
||||
{{ end }}
|
||||
{{ $detectorProducts = merge $detectorProducts (dict $key $productData) }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<div class="modal-content" id="influxdb-version-detector">
|
||||
<div data-component="influxdb-version-detector"
|
||||
data-products='{{ $detectorProducts | jsonify }}'
|
||||
data-influxdb-urls='{{ site.Data.influxdb_urls | jsonify }}'></div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
{{/*
|
||||
InfluxDB Version Detector Modal Trigger Shortcode
|
||||
Usage: {{< influxdb-version-detector >}}
|
||||
Usage with Ask AI integration: {{< influxdb-version-detector context="grafana" ai_instruction="Help me use [context] with [influxdb_version]" >}}
|
||||
|
||||
This shortcode creates a button that opens a modal with the InfluxDB version detector component.
|
||||
The component helps users identify which InfluxDB product they're using through a guided questionnaire.
|
||||
|
||||
Parameters:
|
||||
- context: Optional context for Ask AI integration (e.g., "grafana")
|
||||
- ai_instruction: Optional instruction template for Ask AI with placeholders [context] and [influxdb_version]
|
||||
*/}}
|
||||
|
||||
{{ $context := .Get "context" }}
|
||||
{{ $aiInstruction := .Get "ai_instruction" }}
|
||||
|
||||
<h4>Identify your InfluxDB version</h4>
|
||||
|
||||
<p>
|
||||
If you are unsure which InfluxDB product you are using, use our interactive version detector to help identify it:</p>
|
||||
|
||||
<p>
|
||||
{{ if $context }}
|
||||
<a href="#"
|
||||
class="btn influxdb-detector-trigger"
|
||||
data-context="{{ $context }}"
|
||||
{{ if $aiInstruction }}data-ai-instruction="{{ $aiInstruction }}"{{ end }}
|
||||
onclick="
|
||||
if (window.gtag) {
|
||||
window.gtag('event', 'influxdb_version_detector', {
|
||||
'custom_map.interaction_type': 'modal_trigger',
|
||||
'custom_map.section': location.pathname,
|
||||
'custom_map.context': '{{ $context }}'
|
||||
});
|
||||
}
|
||||
window.influxdatadocs.toggleModal('#influxdb-version-detector');
|
||||
return false;
|
||||
">
|
||||
Detect my InfluxDB version
|
||||
</a>
|
||||
{{ else }}
|
||||
<a href="#"
|
||||
class="btn influxdb-detector-trigger"
|
||||
onclick="
|
||||
if (window.gtag) {
|
||||
window.gtag('event', 'influxdb_version_detector', {
|
||||
'custom_map.interaction_type': 'modal_trigger',
|
||||
'custom_map.section': location.pathname
|
||||
});
|
||||
}
|
||||
window.influxdatadocs.toggleModal('#influxdb-version-detector');
|
||||
return false;
|
||||
">
|
||||
Detect my InfluxDB version
|
||||
</a>
|
||||
{{ end }}
|
||||
</p>
|
||||
|
||||
{{ if and $context $aiInstruction }}
|
||||
<!-- Ask AI integration will be implemented in the TypeScript component -->
|
||||
{{ end }}
|
||||
|
|
@ -82,6 +82,10 @@ pre-commit:
|
|||
run: '.ci/vale/vale.sh
|
||||
--config=content/influxdb/v2/.vale.ini
|
||||
--minAlertLevel=error {staged_files}'
|
||||
build-typescript:
|
||||
glob: "assets/js/*.ts"
|
||||
run: yarn build:ts
|
||||
stage_fixed: true
|
||||
prettier:
|
||||
tags: [frontend, style]
|
||||
glob: '*.{css,js,ts,jsx,tsx}'
|
||||
|
|
@ -108,7 +112,7 @@ pre-push:
|
|||
- content/example.md
|
||||
run: |
|
||||
echo "Running shortcode examples test due to changes in: {staged_files}"
|
||||
node cypress/support/run-e2e-specs.js --spec "cypress/e2e/content/article-links.cy.js" content/example.md
|
||||
node cypress/support/run-e2e-specs.js --spec "cypress/e2e/content/index.cy.js" content/example.md
|
||||
exit $?
|
||||
|
||||
# Manage Docker containers
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@
|
|||
"scripts": {
|
||||
"build:pytest:image": "docker build -t influxdata/docs-pytest:latest -f Dockerfile.pytest .",
|
||||
"build:agent:instructions": "node ./helper-scripts/build-agent-instructions.js",
|
||||
"build:ts": "tsc --project tsconfig.json --outDir dist",
|
||||
"build:ts:watch": "tsc --project tsconfig.json --outDir dist --watch",
|
||||
"lint": "LEFTHOOK_EXCLUDE=test lefthook run pre-commit && lefthook run pre-push",
|
||||
"pre-commit": "lefthook run pre-commit",
|
||||
"test": "echo \"Run 'yarn test:e2e', 'yarn test:links', 'yarn test:codeblocks:all' or a specific test command. e2e and links test commands can take a glob of file paths to test. Some commands run automatically during the git pre-commit and pre-push hooks.\" && exit 0",
|
||||
|
|
@ -55,7 +57,7 @@
|
|||
"test:codeblocks:v2": "docker compose run --rm --name v2-pytest v2-pytest",
|
||||
"test:codeblocks:stop-monitors": "./test/scripts/monitor-tests.sh stop cloud-dedicated-pytest && ./test/scripts/monitor-tests.sh stop clustered-pytest",
|
||||
"test:e2e": "node cypress/support/run-e2e-specs.js",
|
||||
"test:shortcode-examples": "node cypress/support/run-e2e-specs.js --spec \"cypress/e2e/content/article-links.cy.js\" content/example.md"
|
||||
"test:shortcode-examples": "node cypress/support/run-e2e-specs.js --spec \"cypress/e2e/content/index.cy.js\" content/example.md"
|
||||
},
|
||||
"type": "module",
|
||||
"browserslist": [
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 291 KiB |
|
After Width: | Height: | Size: 322 KiB |
|
After Width: | Height: | Size: 329 KiB |
|
After Width: | Height: | Size: 360 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 305 KiB |
|
After Width: | Height: | Size: 324 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 440 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 350 KiB |
|
After Width: | Height: | Size: 335 KiB |
|
After Width: | Height: | Size: 290 KiB |
|
After Width: | Height: | Size: 324 KiB |
|
After Width: | Height: | Size: 283 KiB |
|
After Width: | Height: | Size: 334 KiB |
|
After Width: | Height: | Size: 280 KiB |
|
After Width: | Height: | Size: 322 KiB |
|
After Width: | Height: | Size: 296 KiB |
|
After Width: | Height: | Size: 409 KiB |
|
After Width: | Height: | Size: 244 KiB |
|
After Width: | Height: | Size: 362 KiB |
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./assets/js",
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"noEmit": false,
|
||||
"isolatedModules": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": [
|
||||
"assets/js/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"public",
|
||||
"resources",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
|
|
@ -1126,9 +1126,9 @@ callsites@^3.0.0:
|
|||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||
|
||||
caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001737:
|
||||
version "1.0.30001739"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz#b34ce2d56bfc22f4352b2af0144102d623a124f4"
|
||||
integrity sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==
|
||||
version "1.0.30001745"
|
||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001745.tgz"
|
||||
integrity sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==
|
||||
|
||||
careful-downloader@^3.0.0:
|
||||
version "3.0.0"
|
||||
|
|
|
|||