Merge pull request #6446 from influxdata/update-grafana-docs

New tools: Grafana plugin update, InfluxDB 3 ODBC and PowerBI connectors
pull/6451/head
Jason Stirnaman 2025-10-06 22:26:37 -05:00 committed by GitHub
commit 819edf7a99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
90 changed files with 6620 additions and 791 deletions

View File

@ -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

View File

@ -36,6 +36,7 @@ Redoc
SQLAlchemy
SQLAlchemy
Splunk
System.Data.Odbc
[Ss]uperset
TBs?
\bUI\b

545
.github/agents/typescript-hugo-agent.md vendored Normal file
View File

@ -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)

View File

@ -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`.

View File

@ -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._

3
.gitignore vendored
View File

@ -35,6 +35,9 @@ tmp
.idea
**/config.toml
# TypeScript build output
**/dist/
# User context files for AI assistant tools
.context/*
!.context/README.md

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}
}
}
}

View File

@ -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;

View File

@ -34,3 +34,6 @@
"layouts/code-controls",
"layouts/v3-wayfinding";
// Import Components
@import "components/influxdb-version-detector";

View File

@ -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/).

View File

@ -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

View File

@ -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/).

View File

@ -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
---

View File

@ -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"
> ```
>

View File

@ -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/

View File

@ -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/

View File

@ -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/

View File

@ -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 -->

View File

@ -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/)

View File

@ -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 -->

View File

@ -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"
> ```
>

View File

@ -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/

View File

@ -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/

View File

@ -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 -->

View File

@ -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/)

View File

@ -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 -->

View File

@ -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"
> ```
>

View File

@ -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/

View File

@ -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/

View File

@ -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/

View File

@ -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 -->

View File

@ -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/)

View File

@ -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 -->

View File

@ -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 -->

View File

@ -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 -->

View File

@ -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 -->

View File

@ -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 -->

View File

@ -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 -->

View File

@ -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 -->

View File

@ -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.

View File

@ -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/).

View File

@ -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" %}}&nbsp;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

View File

@ -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/).

View File

@ -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

View File

@ -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/).

View File

@ -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

View File

@ -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;
});
});
});
});

View File

@ -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';

View File

@ -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)');
}
});
});

View File

@ -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

View File

@ -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?

View File

@ -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',
],
},

View File

@ -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" . }}

View File

@ -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>

View File

@ -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 }}

View File

@ -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

View File

@ -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": [

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

34
tsconfig.json Normal file
View File

@ -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"
]
}

View File

@ -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"