From cb37ee2574d9b68fb7791029e135962bdda750cc Mon Sep 17 00:00:00 2001 From: Jason Stirnaman Date: Tue, 6 Jan 2026 09:57:47 -0600 Subject: [PATCH 1/3] fix: tab names in generated Markdown (#6698) - maintains semantic flow of tab labels and code-tab labels with their tab contents - formats labels in bold to avoid breaking heading level semantics - wraps tabbed content in begin/end comments to denote options --- scripts/lib/markdown-converter.cjs | 170 ++++++++++++++++++++++++----- 1 file changed, 144 insertions(+), 26 deletions(-) diff --git a/scripts/lib/markdown-converter.cjs b/scripts/lib/markdown-converter.cjs index de8545608..a63a98bce 100644 --- a/scripts/lib/markdown-converter.cjs +++ b/scripts/lib/markdown-converter.cjs @@ -45,9 +45,18 @@ const URL_PATTERN_MAP = { const PRODUCT_NAME_MAP = { influxdb3_core: { name: 'InfluxDB 3 Core', version: 'core' }, - influxdb3_enterprise: { name: 'InfluxDB 3 Enterprise', version: 'enterprise' }, - influxdb3_cloud_dedicated: { name: 'InfluxDB Cloud Dedicated', version: 'cloud-dedicated' }, - influxdb3_cloud_serverless: { name: 'InfluxDB Cloud Serverless', version: 'cloud-serverless' }, + influxdb3_enterprise: { + name: 'InfluxDB 3 Enterprise', + version: 'enterprise', + }, + influxdb3_cloud_dedicated: { + name: 'InfluxDB Cloud Dedicated', + version: 'cloud-dedicated', + }, + influxdb3_cloud_serverless: { + name: 'InfluxDB Cloud Serverless', + version: 'cloud-serverless', + }, influxdb3_clustered: { name: 'InfluxDB Clustered', version: 'clustered' }, influxdb3_explorer: { name: 'InfluxDB 3 Explorer', version: 'explorer' }, influxdb_cloud: { name: 'InfluxDB Cloud (TSM)', version: 'cloud' }, @@ -81,12 +90,18 @@ function detectBaseUrl() { } // Check if Hugo dev server is running on localhost - if (process.env.HUGO_ENV === 'development' || process.env.NODE_ENV === 'development') { + if ( + process.env.HUGO_ENV === 'development' || + process.env.NODE_ENV === 'development' + ) { return 'http://localhost:1313'; } // Check for staging environment - if (process.env.HUGO_ENV === 'staging' || process.env.DEPLOY_ENV === 'staging') { + if ( + process.env.HUGO_ENV === 'staging' || + process.env.DEPLOY_ENV === 'staging' + ) { return process.env.STAGING_URL || 'https://test2.docs.influxdata.com'; } @@ -277,6 +292,79 @@ function createTurndownService() { }, }); + // Handle tabbed content - associate tab names with their content + // This rule handles both .tabs-wrapper and .code-tabs-wrapper containers + turndownService.addRule('tabbedContent', { + filter: function (node) { + return ( + node.nodeName === 'DIV' && + node.classList && + (node.classList.contains('tabs-wrapper') || + node.classList.contains('code-tabs-wrapper')) + ); + }, + replacement: function (_content, node, options) { + const isCodeTabs = node.classList.contains('code-tabs-wrapper'); + const tabsSelector = isCodeTabs ? '.code-tabs' : '.tabs'; + const contentSelector = isCodeTabs ? '.code-tab-content' : '.tab-content'; + + // Extract tab names from anchor elements + const tabsContainer = node.querySelector(tabsSelector); + const tabLinks = tabsContainer + ? Array.from(tabsContainer.querySelectorAll('a')) + : []; + const tabNames = tabLinks.map((link) => link.textContent.trim()); + + // Extract tab content sections + // Note: :scope selector is not supported in Turndown's DOM parser, + // so we use a simple selector and filter by parent + const allContentSections = Array.from( + node.querySelectorAll(contentSelector) + ); + // Filter to only direct children of the tabs-wrapper + const contentSections = allContentSections.filter( + (section) => section.parentNode === node + ); + + // If no tabs or content found, fall back to default conversion + if (tabNames.length === 0 || contentSections.length === 0) { + return _content; + } + + // Build markdown with explicit tab-content association + // Use bold labels instead of headings to avoid breaking heading hierarchy + const parts = []; + + // Add a comment indicating this is tabbed content + parts.push( + '\n\n' + ); + + // Process each tab and its content + const maxTabs = Math.max(tabNames.length, contentSections.length); + for (let i = 0; i < maxTabs; i++) { + const tabName = tabNames[i] || `Tab ${i + 1}`; + const contentSection = contentSections[i]; + + // Add tab label with bold formatting (not a heading to preserve hierarchy) + parts.push(`\n**${tabName}:**\n`); + + if (contentSection) { + // Recursively convert the content inside the tab + const innerHtml = contentSection.innerHTML; + const innerContent = turndownService.turndown(innerHtml); + parts.push(innerContent.trim()); + } + + parts.push('\n'); + } + + parts.push('\n\n'); + + return parts.join('\n'); + }, + }); + // Remove navigation, footer, and other non-content elements turndownService.remove([ 'nav', @@ -398,9 +486,9 @@ function generateFrontmatter(metadata, urlPath, baseUrl = '') { // Sanitize description (remove newlines, truncate to reasonable length) let description = metadata.description || ''; description = description - .replace(/\s+/g, ' ') // Replace all whitespace (including newlines) with single space + .replace(/\s+/g, ' ') // Replace all whitespace (including newlines) with single space .trim() - .substring(0, 500); // Truncate to 500 characters max + .substring(0, 500); // Truncate to 500 characters max // Add token estimate (rough: 4 chars per token) const contentLength = metadata.content?.length || 0; @@ -414,7 +502,7 @@ function generateFrontmatter(metadata, urlPath, baseUrl = '') { title: metadata.title, description: description, url: fullUrl, - estimated_tokens: estimatedTokens + estimated_tokens: estimatedTokens, }; if (product) { @@ -425,10 +513,16 @@ function generateFrontmatter(metadata, urlPath, baseUrl = '') { } // Serialize to YAML (handles special characters properly) - return '---\n' + yaml.dump(frontmatterObj, { - lineWidth: -1, // Disable line wrapping - noRefs: true // Disable anchors/aliases - }).trim() + '\n---'; + return ( + '---\n' + + yaml + .dump(frontmatterObj, { + lineWidth: -1, // Disable line wrapping + noRefs: true, // Disable anchors/aliases + }) + .trim() + + '\n---' + ); } /** @@ -439,15 +533,20 @@ function generateFrontmatter(metadata, urlPath, baseUrl = '') { * @param {string} baseUrl - Base URL for full URL construction * @returns {string} YAML frontmatter as string */ -function generateSectionFrontmatter(metadata, urlPath, childPages, baseUrl = '') { +function generateSectionFrontmatter( + metadata, + urlPath, + childPages, + baseUrl = '' +) { const product = detectProduct(urlPath); // Sanitize description (remove newlines, truncate to reasonable length) let description = metadata.description || ''; description = description - .replace(/\s+/g, ' ') // Replace all whitespace (including newlines) with single space + .replace(/\s+/g, ' ') // Replace all whitespace (including newlines) with single space .trim() - .substring(0, 500); // Truncate to 500 characters max + .substring(0, 500); // Truncate to 500 characters max // Add token estimate (rough: 4 chars per token) const contentLength = metadata.content?.length || 0; @@ -469,7 +568,7 @@ function generateSectionFrontmatter(metadata, urlPath, childPages, baseUrl = '') url: fullUrl, type: 'section', pages: childPages.length, - estimated_tokens: estimatedTokens + estimated_tokens: estimatedTokens, }; if (product) { @@ -481,17 +580,23 @@ function generateSectionFrontmatter(metadata, urlPath, childPages, baseUrl = '') // List child pages with full URLs if (childPages.length > 0) { - frontmatterObj.child_pages = childPages.map(child => ({ + frontmatterObj.child_pages = childPages.map((child) => ({ url: normalizedBaseUrl ? `${normalizedBaseUrl}${child.url}` : child.url, - title: child.title + title: child.title, })); } // Serialize to YAML (handles special characters properly) - return '---\n' + yaml.dump(frontmatterObj, { - lineWidth: -1, // Disable line wrapping - noRefs: true // Disable anchors/aliases - }).trim() + '\n---'; + return ( + '---\n' + + yaml + .dump(frontmatterObj, { + lineWidth: -1, // Disable line wrapping + noRefs: true, // Disable anchors/aliases + }) + .trim() + + '\n---' + ); } /** @@ -506,7 +611,9 @@ async function convertToMarkdown(htmlContent, urlPath) { // Detect base URL for the environment const baseUrl = detectBaseUrl(); if (DEBUG) { - console.log(`[DEBUG] Base URL detected: ${baseUrl} (NODE_ENV=${process.env.NODE_ENV}, HUGO_ENV=${process.env.HUGO_ENV}, BASE_URL=${process.env.BASE_URL})`); + console.log( + `[DEBUG] Base URL detected: ${baseUrl} (NODE_ENV=${process.env.NODE_ENV}, HUGO_ENV=${process.env.HUGO_ENV}, BASE_URL=${process.env.BASE_URL})` + ); } // Use Rust converter if available (10× faster) @@ -514,7 +621,10 @@ async function convertToMarkdown(htmlContent, urlPath) { try { return rustConverter.convertToMarkdown(htmlContent, urlPath, baseUrl); } catch (err) { - console.warn(`Rust conversion failed for ${urlPath}, falling back to JavaScript:`, err.message); + console.warn( + `Rust conversion failed for ${urlPath}, falling back to JavaScript:`, + err.message + ); // Fall through to JavaScript implementation } } @@ -563,9 +673,17 @@ async function convertSectionToMarkdown( // Use Rust converter if available (10× faster) if (USE_RUST && rustConverter) { try { - return rustConverter.convertSectionToMarkdown(sectionHtml, sectionUrlPath, childHtmls, baseUrl); + return rustConverter.convertSectionToMarkdown( + sectionHtml, + sectionUrlPath, + childHtmls, + baseUrl + ); } catch (err) { - console.warn(`Rust section conversion failed for ${sectionUrlPath}, falling back to JavaScript:`, err.message); + console.warn( + `Rust section conversion failed for ${sectionUrlPath}, falling back to JavaScript:`, + err.message + ); // Fall through to JavaScript implementation } } From 36f9222fd583fa97a57d01a23466ff0790ad3a93 Mon Sep 17 00:00:00 2001 From: Jason Stirnaman Date: Tue, 6 Jan 2026 10:13:18 -0600 Subject: [PATCH 2/3] feat(sync): extract style attributes from HTML comments (#6694) Add extractStyleAttributes() function to convert headings like: `#### Heading ` to: `#### Heading {.class}` This allows source READMEs to render cleanly on GitHub while still supporting Hugo style classes in docs-v2. --- .../influxdb3-plugins/port_to_docs.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/helper-scripts/influxdb3-plugins/port_to_docs.js b/helper-scripts/influxdb3-plugins/port_to_docs.js index 324bf2bd8..bbc79e6f9 100644 --- a/helper-scripts/influxdb3-plugins/port_to_docs.js +++ b/helper-scripts/influxdb3-plugins/port_to_docs.js @@ -205,6 +205,25 @@ For other InfluxDB versions, see the [Support and feedback](#bug-reports-and-fee return content; } +/** + * Extract style attributes from HTML comments and apply to headings. + * Converts: `#### Heading ` to `#### Heading {.class}` + * + * Supported class formats: + * - {.green}, {.orange} - Color styling + * - {.recommended}, {.not-recommended} - Semantic styling + * - Any other {.classname} format + * + * This allows source READMEs to render cleanly on GitHub (which ignores + * HTML comments) while still supporting Hugo style classes in docs-v2. + */ +function extractStyleAttributes(content) { + // Match headings with HTML comment style attributes + // Pattern: (#+) (heading text) + const pattern = /^(#{1,6})\s+(.+?)\s*\s*$/gm; + return content.replace(pattern, '$1 $2 $3'); +} + /** * Ensure code blocks are properly formatted. */ @@ -277,6 +296,7 @@ function transformContent(content, pluginName, config) { content = convertTomlReadmeLinks(content); content = addProductShortcodes(content); content = enhanceOpeningParagraph(content); + content = extractStyleAttributes(content); content = fixCodeBlockFormatting(content); // Add schema requirements if applicable From 1203602607734509674de74a4e56602a9f7066fc Mon Sep 17 00:00:00 2001 From: Jason Stirnaman Date: Tue, 6 Jan 2026 14:01:49 -0600 Subject: [PATCH 3/3] docs(influxdb3): document log-filter values and targeted filtering (#6695) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(link-checker): update configs for v1.3.0 severity classification Remove exclusions for sites that return 403/429 (bot protection) and 5xx (server errors) - these are now handled by severity classification: - 403/401/429 → info (shown but don't fail CI) - 5xx/timeout → warning (shown but don't fail CI) - 404/410/DNS → error (fail CI) Removed exclusions: - GitHub, Slack, Reddit, StackOverflow - Docker Hub, Grafana, Microsoft Learn - Claude.ai, Dremio, Scarf, InfluxData support Kept exclusions: - Localhost/local network URLs - Example/placeholder URLs - CI-specific workarounds (canonical URLs, file fragments) Added [severity] configuration section with default thresholds. * docs(influxdb3): document log-filter values and targeted filtering Add comprehensive documentation for the --log-filter configuration option: - Log levels table (error, warn, info, debug, trace) - Targeted filtering syntax for specific components - Common component names for Core and Enterprise - Debug logging section in write troubleshoot page closes influxdata/DAR#575 * Update content/shared/influxdb3-cli/config-options.md --- .gitignore | 1 + .../shared/influxdb3-cli/config-options.md | 87 ++++++++++++++++++- .../influxdb3-write-guides/troubleshoot.md | 27 +++++- 3 files changed, 113 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 5b5487a3d..3cd0d666d 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ tmp # User context files for AI assistant tools .context/* !.context/README.md +.task.md # External repos .ext/* diff --git a/content/shared/influxdb3-cli/config-options.md b/content/shared/influxdb3-cli/config-options.md index 46796551c..3723912dd 100644 --- a/content/shared/influxdb3-cli/config-options.md +++ b/content/shared/influxdb3-cli/config-options.md @@ -832,7 +832,92 @@ Sets the endpoint of an S3-compatible, HTTP/2-enabled object store cache. #### log-filter -Sets the filter directive for logs. +Sets the filter directive for logs. Use this option to control the verbosity of +server logs globally or for specific components. + +##### Log levels + +The following log levels are available (from least to most verbose): + +| Level | Description | +| :------ | :---------------------------------------------------------------------------------------------------- | +| `error` | Only errors | +| `warn` | Warnings and errors | +| `info` | Informational messages, warnings, and errors _(default)_ | +| `debug` | Debug information for troubleshooting, plus all above levels | +| `trace` | Very detailed tracing information, plus all above levels (produces high log volume) | + +##### Basic usage + +To set the log level globally, pass one of the log levels: + + + +```sh +influxdb3 serve --log-filter debug +``` + +##### Targeted filtering + +Globally enabling `debug` or `trace` produces a high volume of log output. +For more targeted debugging, you can set different log levels for specific +components using the format `,=`. + +###### Debug write buffer operations + + + +```sh +influxdb3 serve --log-filter info,influxdb3_write_buffer=debug +``` + +###### Trace WAL operations + + + +```sh +influxdb3 serve --log-filter info,influxdb3_wal=trace +``` + +###### Multiple targeted filters + + + +```sh +influxdb3 serve --log-filter info,influxdb3_write_buffer=debug,influxdb3_wal=debug +``` + +{{% show-in "enterprise" %}} + +###### Debug Enterprise storage engine operations + + + +```sh +influxdb3 serve --log-filter info,influxdb3_pacha_tree=debug +``` + +{{% /show-in %}} + +##### Common component names + +The following are common component names you can use for targeted filtering: + +| Component | Description | +| :------------------------------------ | :------------------------------------------------------- | +| `influxdb3_write_buffer` | Write buffer operations | +| `influxdb3_wal` | Write-ahead log operations | +| `influxdb3_catalog` | Catalog and schema operations | +| `influxdb3_cache` | Caching operations | +{{% show-in "enterprise" %}}`influxdb3_pacha_tree` | Enterprise storage engine operations | +`influxdb3_enterprise` | Enterprise-specific features | +{{% /show-in %}} + +> [!Note] +> Targeted filtering requires knowledge of the codebase component names. +> The component names correspond to Rust package names in the InfluxDB 3 source +> code. Use `debug` or `trace` sparingly on specific components to avoid +> excessive log output. | influxdb3 serve option | Environment variable | | :--------------------- | :------------------- | diff --git a/content/shared/influxdb3-write-guides/troubleshoot.md b/content/shared/influxdb3-write-guides/troubleshoot.md index 4b998e152..bd4430cd0 100644 --- a/content/shared/influxdb3-write-guides/troubleshoot.md +++ b/content/shared/influxdb3-write-guides/troubleshoot.md @@ -6,7 +6,8 @@ Learn how to avoid unexpected results and recover from errors when writing to - [Review HTTP status codes](#review-http-status-codes) - [Troubleshoot failures](#troubleshoot-failures) - [Troubleshoot rejected points](#troubleshoot-rejected-points) -{{% show-in "core,enterprise" %}}- [Troubleshoot write performance issues](#troubleshoot-write-performance-issues){{% /show-in %}} +{{% show-in "core,enterprise" %}}- [Troubleshoot write performance issues](#troubleshoot-write-performance-issues) + - [Use debug logs for troubleshooting](#use-debug-logs-for-troubleshooting){{% /show-in %}} ## Handle write responses @@ -105,4 +106,28 @@ influxdb3 serve \ Replace {{% code-placeholder-key %}}`PERCENTAGE`{{% /code-placeholder-key %}} with the percentage of available memory to allocate (for example, `35%` for write-heavy workloads). +### Use debug logs for troubleshooting + +For deeper investigation of write issues, enable debug logging for specific +components. Debug logs provide detailed information about write buffer +operations and WAL activity. + +To enable debug logs for write operations, restart {{% product-name %}} with +targeted log filters: + + + +```sh +influxdb3 serve --log-filter info,influxdb3_write_buffer=debug +``` + + + +```sh +influxdb3 serve --log-filter info,influxdb3_wal=debug +``` + +For more information about log levels and targeted filtering, see +[log-filter configuration](/influxdb3/version/reference/config-options/#log-filter). + {{% /show-in %}}