今日已更新 339 条资讯 | 累计 19899 条内容
关于我们

标签:#tutorial

找到 368 篇相关文章

AI 资讯

Adding real payments to a Base44 app (3 insertion points, tested)

Disclosure up front: I'm Oded, co-founder of UniPaaS, the FCA-authorised Payment Institution (No. 929994) behind paas.build - so this is a vendor writing about his own product. That said, the three Base44 mechanics below are documented Base44 surfaces, and they work with any external payments API, not just ours. The wall Tell Base44 "add payments" and it installs Stripe or Base44 Payments (powered by Wix), plus Tranzila/Max for Israel. Both main options are solid if you qualify: Stripe is excellent infrastructure with first-class docs, and the Wix-powered option is native to the platform. The fine print is where builders hit a wall: Stripe live mode needs verified business and banking information before you can take a real payment. Base44 Payments requires "a business and bank account based in one of the supported countries" (their docs). The top payments request on Base44's own feedback board is "a way to setup other payment providers other than Stripe" - precisely because not every country is supported. Base44 webhooks only fire while someone is actively using your app, so 3am subscription renewals, retries and dunning silently don't run. If you have a registered company in a supported country and mostly sell one-off purchases, use the built-in Stripe path. It's the smoothest. The rest of this post is for everyone else. Base44 gives you three documented ways to wire in an external provider. I tested all three with paas.build. Here's each, and when it fits. Insertion point 1: custom MCP connection (build-time) In Base44: Settings → Account → MCP connections → Add custom MCP . Name: paas.build Server URL: https://paas.build/sse Auth: API key (your paas.build key) That's the legacy SSE endpoint Base44's form takes; streamable HTTP lives at https://paas.build/mcp for agents that support it. Base44's AI treats MCP connections as tools it can call when your request needs external data or actions. So in the editor chat you can say "use paas.build to create a live merchan

2026-07-10 原文 →
AI 资讯

How to Anonymize PII in Text with an API

What Is Data Masking? Data masking is a technique that replaces sensitive information with realistic but fictitious data, preserving the format and structure of the original while removing its identifiable meaning. The goal is to keep data usable for development, testing, analytics, or sharing — without exposing real personally identifiable information (PII). Common masking techniques include: Substitution — Replace a real value with a plausible fake (e.g., Alice Smith → Jane Doe ). Masking (partial obscuring) — Show only a portion of the value (e.g., 4111-1111-1111-1234 → ****-****-****-1234 ). Redaction — Remove the value entirely. Hashing — Replace with a cryptographic hash. Irreversible, but deterministic when salted. Data masking is widely used in non-production environments, analytics pipelines, data marketplaces, and any scenario where real PII is not needed but structural fidelity is. What Is Dynamic Data Masking? Static data masking (SDM) applies transformations to data at rest — you clone a production database, mask it, and ship the masked copy to a lower environment. The masking happens once, and the result is a permanent dataset. Dynamic data masking (DDM) applies transformations on the fly , at query or API time, based on who is asking. The original data stays untouched; the masking rules are applied in the response layer. This means: Different roles see different levels of detail (e.g., support agents see the last 4 digits of a credit card; auditors see the full number). No masked copies to maintain — one source of truth, many views. Masking policies are centralized and enforceable without application changes. Veramask implements a DDM-style model over an API: you send a request with payload and settings, and receive back the transformed result in real time. No data is persisted on the server — each call is independent and stateless. Anonymizing PII with the Veramask API Veramask exposes two endpoints for dynamic PII masking: Endpoint Input Use Case PO

2026-07-10 原文 →
AI 资讯

How to Create a Skill in Claude Code

This is a cross-post — the original (and any updates) live at broke2builtai.com . The first time I watched Claude Code reach for a skill I hadn't told it to use — read a folder, run the script inside it, and hand back the finished thing — the difference from a slash command finally landed. A slash command waits for you to type it. A skill waits for the situation . Claude decides. That one shift is the whole feature, and building one takes about five minutes once you know where the file goes. Here's the entire thing end to end, including the one gotcha that decides whether your skill ever actually fires. What a Skill actually is A Skill is a folder with a SKILL.md file inside it. The Markdown holds instructions; the YAML frontmatter at the top holds a name and a description . That description is doing the most important job in the whole file: Claude reads it to decide, on its own, whether the current task warrants invoking the skill. Nothing else you write matters if the description doesn't get you picked. That's the mental model to hold onto: a custom slash command is a prompt you trigger by typing /name ; a skill is a procedure Claude triggers when the context matches. Same reusable-instructions idea, opposite trigger. Where the file goes Two locations register, exactly like commands and subagents : Project skill — .claude/skills/<skill-name>/SKILL.md inside the repo. Committed, so your whole team gets it. Personal skill — ~/.claude/skills/<skill-name>/SKILL.md in your home directory. Follows you across every project on your machine. Each skill is its own folder, and the folder name should match the name in the frontmatter. A loose SKILL.md sitting somewhere else won't be picked up. The minimum viable skill Create the folder and the file: .claude/skills/pytest-runner/SKILL.md Then write the two-part file — frontmatter, then body: --- name : pytest-runner description : " Run, generate, or debug pytest tests for this project. Use when the user asks to run the test su

2026-07-10 原文 →
AI 资讯

Palette quantization notes: reducing colors without making an image muddy

I’ve been thinking about a small image-processing problem lately: how to reduce an image to a limited palette without making it look muddy. This comes up in a lot of places: pixel art tools printable pattern generators low-color previews LED matrix displays icons and small thumbnails craft or grid-based workflows The easy version is: pick the nearest color for every pixel. The hard version is: keep the important shapes readable after the palette gets much smaller. Nearest color is only the baseline A simple nearest-color pass usually works like this: Take each pixel. Compare it with every color in the target palette. Pick the closest one. Replace the pixel. That gives you a valid output, but not always a good one. The problem is that closest is local. It does not know whether the whole image still reads well. A face can lose warm midtones. A shadow can turn into a flat dark blob. A small highlight can disappear. Skin, fur, fabric, and background colors can collapse into the same bucket. So palette reduction is not just a color problem. It is also a structure problem. RGB distance can be misleading A common first attempt is Euclidean distance in RGB: function rgbDistance(a, b) { return Math.sqrt( (a.r - b.r) ** 2 + (a.g - b.g) ** 2 + (a.b - b.b) ** 2 ); } This is easy to implement, but it does not match human perception very well. Two colors can be numerically close in RGB and still feel different. Other colors can be farther apart numerically but visually acceptable. A better approach is to compare colors in a more perceptual color space, such as Lab or OKLab. You still have to be careful, but the distance metric starts closer to what the eye notices. Dithering helps, but it changes the style Error diffusion, like Floyd-Steinberg dithering, can preserve gradients and perceived detail with fewer colors. That is useful when the output is meant to look like a low-color image. But dithering is not always desirable. In grid-based outputs, it can create scattered single-p

2026-07-10 原文 →
AI 资讯

Query SEC filings from inside Claude Desktop — Filingrail is now MCP-enabled

Filingrail now ships a first-party MCP server on PyPI: pip install filingrail-mcp . One install, one config block, and Claude Desktop — or Cursor, or Continue, or any MCP-compatible client — can query SEC filings as tools. No glue code. That's worth naming directly. Most SEC-data APIs ship a REST endpoint and stop. You write the agent integration yourself: parse the response, wire up the tool schema, handle auth headers. Filingrail ships the integration as a maintained package with the same update cadence as the underlying REST API. This post covers the setup, what you can ask once it's wired in, and the honest limits. I built both the API and the MCP server — I'll be upfront about that throughout. This post covers a data API that returns SEC-registered financial information. Nothing here is investment advice. Two ways to wire it in Option 1 — pip install filingrail-mcp (recommended) Install the package, add one block to your Claude Desktop config, restart. Filingrail's endpoints appear as tools. No separate service to run, no background daemon. Option 2 — RapidAPI MCP Playground tab (no local install) The Filingrail listing on RapidAPI has an MCP tab that generates a ready-to-paste config block. Same endpoints, same auth, zero install step. Either path gives Claude the same tools. Pick the one that fits your setup. Setup — the pip install path You'll need Python 3.10+ and a RapidAPI key. 1. Subscribe to Filingrail Go to the Filingrail RapidAPI listing and subscribe. Free tier is 50 calls/day, no credit card. Copy your X-RapidAPI-Key from the RapidAPI dashboard. 2. Install the server pip install filingrail-mcp 3. Add Filingrail to your Claude Desktop config On macOS: ~/Library/Application Support/Claude/claude_desktop_config.json On Windows: %APPDATA%\Claude\claude_desktop_config.json { "mcpServers" : { "filingrail" : { "command" : "filingrail-mcp" , "env" : { "RAPIDAPI_KEY" : "your_rapidapi_key_here" } } } } 4. Restart Claude Desktop Filingrail's endpoints appear a

2026-07-09 原文 →
AI 资讯

LED Strip Tetris: Zero-Code Hardware Game with TuyaOpen + Claude Code Tutorial

I built an LED Strip Tetris game — without writing a single line of code. No keyboard mashing. No debugging at 2 AM. No reading 500 pages of datasheets. Just natural language prompts, an AI agent, and a Tuya T5 AI Core board. Here's the full breakdown of how it works 👇 🧩 What Is LED Strip Tetris? LED Strip Tetris is a DIY hardware game built entirely through natural language prompts using TuyaOpen IDE and Claude Code. It runs on a Tuya T5 AI Core development board with a WS2812 LED strip (72 LEDs) and three color-matched buttons — red, green, and blue. Colored LEDs fall from the top of the strip; players press the matching button to shoot a colored LED upward and eliminate the falling one on contact. The entire game — firmware, game logic, hardware wiring, sound effects, compilation, and flashing — was generated by AI. Zero manual coding. 🔌 The Hardware (Ridiculously Simple) Component Role Tuya T5 AI Core Board Main MCU — runs game logic, drives LED strip and buttons WS2812 LED Strip (72 LEDs) Display — colored LEDs fall and get eliminated 3 Push Buttons (Red / Green / Blue) Input — shoot matching color upward to clear falling LEDs Speaker Sound effects on button press That's it. No custom PCB. No complex wiring harness. Just four components plugged into a dev board. 🤔 Why This Is a Big Deal Here's what building a hardware game normally looks like: Step Traditional Approach Vibe Coding with TuyaOpen IDE Dev environment setup Install toolchain, configure SDK, fight dependencies Copy a workflow link, paste into Claude Code, click confirm Game logic Write C code from scratch, design state machines Describe the game in one sentence, AI generates the code Hardware config Read datasheets, look up GPIO mappings, manually configure Tell AI which pins you're using, it handles the rest Sound effects Write audio decoding code, integrate codecs Give AI the file path, it decodes and compiles Debugging Serial logs, oscilloscope, hours of trial and error AI self-diagnoses compile

2026-07-09 原文 →
AI 资讯

My favourite zsh/bash shortcuts (functions and aliases)

Introduction My zsh profile is over 1000 lines at this point. A lot of that is functions I asked AI to generate for me, since it's fast, portable, and saves me a ton of typing. Here's the thing though: the shortcuts that save me the most time aren't the clever ones. They're the dumb ones. Things like clone instead of git clone && cd , or dir instead of mkdir -p && cd . Each one only saves a second or two, but I run them so often that it adds up fast. These are in no particular order, just the ones I reach for constantly. Git aliases for common commands A few one-liners I have set up as plain aliases: alias gcp = "git cherry-pick" alias git-append = "git commit --amend --no-edit -a" gcp is self-explanatory. git-append amends the last commit with your currently staged (and unstaged, thanks to -a ) changes without touching the commit message. Great for fixing up a commit you just made before you push. Create a branch or switch to it if it already exists One of my most-used functions. Normally you have to remember whether a branch exists before deciding between git checkout <branch> and git checkout -b <branch> . This just does the right thing either way: gb () { if git rev-parse --verify --quiet " $1 " > /dev/null ; then git checkout " $1 " else git checkout -b " $1 " fi } Nuke all local changes to reset the working tree When an experiment goes sideways or I just want to throw everything away and start clean, I run nah : nah () { git reset --hard git clean -df if [ -d ".git/rebase-apply" ] || [ -d ".git/rebase-merge" ] ; then git rebase --abort fi } This resets tracked changes, removes untracked files and directories. No confirmation prompt, so use it carefully. Print recent commits as ready-to-paste cherry-pick commands Useful when you need to cherry-pick a batch of commits from one branch onto another in order: logs () { if [[ -z " $1 " || " $1 " = ~ [ ^0-9] ]] ; then echo "Usage: logs <number_of_commits>" return 1 fi git log -n " $1 " --reverse --pretty = format: "g

2026-07-09 原文 →
AI 资讯

Building an E-commerce Backend: Auth, Cart, and Transactional Orders with Prisma

This is the second stage of my CodeAlpha Full Stack internship — two projects, built in a deliberate order so the patterns from the first carry forward. First was a project management tool (auth + real-time updates with Socket.io). This one is a store: products, cart, orders. Same stack — Express, Prisma, PostgreSQL, JWT — but the interesting part isn't the CRUD, it's the order-placement flow, which is the first genuinely transactional piece of logic in the whole internship. I'll walk through the schema decisions, the auth changes from project one, and then spend most of the time on the part that actually matters: making sure an order can never be created without correctly and atomically updating stock and clearing the cart. The schema model User { id String @id @default(cuid()) name String email String @unique password String role String @default("USER") createdAt DateTime @default(now()) orders Order[] cartItems CartItem[] } model Product { id String @id @default(cuid()) name String description String price Float image String? stock Int @default(0) category String createdAt DateTime @default(now()) cartItems CartItem[] orderItems OrderItem[] } model CartItem { id String @id @default(cuid()) quantity Int @default(1) user User @relation(fields: [userId], references: [id]) userId String product Product @relation(fields: [productId], references: [id]) productId String @@unique([userId, productId]) } model Order { id String @id @default(cuid()) status String @default("PENDING") total Float createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id]) userId String items OrderItem[] } model OrderItem { id String @id @default(cuid()) quantity Int price Float order Order @relation(fields: [orderId], references: [id]) orderId String product Product @relation(fields: [productId], references: [id]) productId String } Two decisions worth explaining, because they're easy to get wrong if you're building this for the first time. OrderItem.price is a

2026-07-09 原文 →
AI 资讯

Applying SAST to Infrastructure as Code (Without TFSec)

Static analysis isn't just for application source code. Terraform, Pulumi, OpenTofu, and CloudFormation files are code too — and they get misconfigured just as often as a backend service. A public S3 bucket, a security group open to 0.0.0.0/0 , or an unencrypted RDS instance are all bugs you can catch before apply ever runs. TFSec is the tool most people reach for first, but it's not the only option on the OWASP Source Code Analysis Tools list . In this article I'll use Checkov , a free, open-source policy-as-code scanner built by Bridgecrew (now part of Palo Alto Networks), to scan a Terraform project end to end — from a local scan to a GitHub Actions gate that blocks merges on critical misconfigurations. The same approach works with OpenTofu and Pulumi projects too, since Checkov understands HCL directly and also has native support for Pulumi's rendered plan output and CloudFormation/ARM/Kubernetes manifests. Why Checkov? 100% open source (Apache 2.0), actively maintained, thousands of built-in policies. Understands Terraform, OpenTofu, CloudFormation, Kubernetes, Helm, Dockerfile, ARM, Serverless Framework, and Pulumi (via cdktf /synthesized plans) — one tool across most of your IaC surface. No account or API key required to run locally or in CI. Supports custom policies written in Python or YAML if the built-in rule set doesn't cover something specific to your org. ## 1. The sample infrastructure A small AWS setup with a few intentionally introduced misconfigurations — the kind that get merged during a rushed sprint: # main.tf provider "aws" { region = "us-east-1" } resource "aws_s3_bucket" "data" { bucket = "company-app-data-bucket" } # Vulnerable: bucket has no encryption, no versioning, and is publicly readable resource "aws_s3_bucket_acl" "data_acl" { bucket = aws_s3_bucket . data . id acl = "public-read" } resource "aws_security_group" "web" { name = "web-sg" description = "Allow web traffic" # Vulnerable: SSH open to the entire internet ingress { from_port

2026-07-09 原文 →
AI 资讯

Applying SAST to Any Application (Without Sonar, Snyk, Semgrep, or Veracode)

Most "how to add SAST to your pipeline" articles gravitate toward the same four names: SonarQube, Snyk, Semgrep, Veracode. They're solid tools, but they're not the only options, and sometimes you can't use them — budget constraints, air-gapped environments, licensing restrictions, or simply wanting something lightweight that lives entirely in your repo. The OWASP Source Code Analysis Tools page lists dozens of alternatives across every language. In this article I'll walk through applying Bandit , a free, open-source SAST tool for Python, to a real sample application — from finding vulnerabilities locally to wiring it into a CI/CD pipeline with GitHub Actions. The same workflow (install → configure → scan → fail the build on high-severity findings → track results over time) applies almost identically if you swap Bandit for other OWASP-listed tools like Brakeman (Ruby), FindSecBugs (Java), Gosec (Go), or Horusec (multi-language). Why Bandit? 100% open source (Apache 2.0), maintained under the PyCQA org. No account, no server, no license key — it runs as a CLI or a library. Understands Python's AST, so it catches real logic patterns, not just regex matches. Easy to tune with a config file and inline # nosec suppressions. ## 1. The sample application Let's use a small Flask app with a few intentionally introduced vulnerabilities — the kind of thing that slips into real codebases under deadline pressure. # app.py import subprocess import sqlite3 import pickle import yaml from flask import Flask , request app = Flask ( __name__ ) DB_PATH = " users.db " @app.route ( " /ping " ) def ping (): host = request . args . get ( " host " ) # Vulnerable: command injection via shell=True result = subprocess . run ( f " ping -c 1 { host } " , shell = True , capture_output = True ) return result . stdout @app.route ( " /user " ) def get_user (): user_id = request . args . get ( " id " ) conn = sqlite3 . connect ( DB_PATH ) cursor = conn . cursor () # Vulnerable: SQL injection via strin

2026-07-09 原文 →
AI 资讯

7 Dockerfile Mistakes That Are Quietly Costing You

Most Dockerfiles work. That's the problem — "it builds and runs" hides a lot of quiet costs in security, speed, and size that don't announce themselves until an audit, an incident, or a cloud bill does it for them. Here are seven mistakes I see constantly, and what to do instead. 1. Running as root By default, the process in your container runs as root — and if someone breaks out, they're root on a surface they shouldn't be. Add a non-root user and switch to it: RUN useradd --system --uid 10001 appuser USER appuser Cheap, and it closes off a whole category of "well, at least it wasn't root" incidents. 2. FROM some-image:latest latest is not a version — it's "whatever was newest when this happened to build." Two builds a week apart can produce different images with no diff to explain it, and a surprise base upgrade is a fun way to spend a Friday. Pin a specific tag, ideally by digest: FROM node:20.11.1-slim 3. Baking secrets into layers COPY .env . or ARG API_KEY followed by using it — and now the secret lives in an image layer forever , recoverable by anyone who pulls the image, even if a later layer deletes the file. Layers are immutable and additive; you can't delete your way out of a leak. Use build secrets ( --mount=type=secret ) or inject at runtime, never at build. 4. No .dockerignore Without one, COPY . . sweeps your .git directory, local env files, node_modules , and test data into the build context — bloating the image and, worse, potentially baking credentials and history into a layer. A five-line .dockerignore is one of the highest-leverage files in the repo. 5. Layer order that destroys your cache COPY . . RUN npm ci # ← reinstalls on EVERY code change Docker invalidates every layer after the first change. Copy the lockfile and install dependencies before copying the rest of your source, so a one-line code change doesn't trigger a full reinstall. This is a build-speed bug hiding as a style choice. 6. Leaving package manager cruft in the image RUN apt-get

2026-07-08 原文 →
开发者

Building malloc from Scratch (Part 1): Architecture & Core Concepts

I wanted to understand how malloc actually works under the hood. Most explanations I found online described what an allocator does, but completely skipped over the "why" behind its design decisions. Rather than stopping at theory, I decided to build a cross-platform allocator in C that implements malloc , calloc , realloc , and free from scratch. This article documents the design of that allocator, the architectural tradeoffs I faced, and the core concepts I had to learn along the way. Table Of Contents Design Decisions Architecture Modern Allocator Strategies Core Concepts What's Next Project Overview A custom memory allocator does not create physical memory. Instead, it requests pages of raw virtual memory from the operating system and manages how that memory is partitioned, reused, resized, and released by the application. The goal of this educational project is to implement C's core memory management API using a modular, cross-platform architecture inspired by design principles found in modern allocators, rather than relying on legacy, single-platform tricks. Design Decisions #1: Why I am Skipping sbrk While many classic tutorials use sbrk for educational implementations, I deliberately chose a 100% mmap -based approach for two major reasons: sbrk is a fragile global bottleneck. It works by moving a single pointer (the program break) up and down. This means the allocator assumes it owns a contiguous line of memory. If a third-party library or another thread in the program secretly calls sbrk behind the scenes, the allocator's memory layout can break instantly. mmap , by contrast, provides isolated, independent chunks of memory. Cross-Platform Symmetry. Windows has absolutely no equivalent to sbrk , but it has a direct equivalent to mmap : VirtualAlloc . If we used sbrk , our architectural abstraction ( os_alloc ) would become awkward because Linux would deal with a moving pointer while Windows dealt with independent pages. Using mmap keeps the abstraction perfec

2026-07-08 原文 →
AI 资讯

DEMYSTIFYING REACT COMPONENT INSTANCES

Hello fellow React developers! In this article we will be breaking down what React component instance is and scenarios where React component instance is at play. What is a React Component ? Before we can understand and really appreciate what a React component instance is, we first need to understand what a component itself is. Basically, components are the fundamental building blocks of any React application. They are independent, reusable pieces of code that allow you to split your application into distinct, manageable bits of logic and UI. From our knowledge of JavaScript, you can think of components in a way as what a function is. Just as we create and use functions to avoid repeating code and separate logic, components are used to divide our application into reusable visual chunks. However, they work in isolation and return HTML (via JSX) to describe what appears on the UI. Let take a look at a simple Greetings component used in a demo; Instead of writing the HTML layout for a greeting over and over again, we define it once as a component and reuse it multiple times in our application by passing different props (arguments). React Component Instances: What are they ? Now that we understand what a React component is, let's move on to React component instances. In programming, an instance is a concrete object created from a specific template (such as a JavaScript class or a Constructor function). In React, a component instance is the actual implementation of a component in a React application. It is a long-lived object that holds contextual information about a particular component. Every time a component is rendered in our application, React creates a new instance of that component. To help you visualize this, let’s take a look at a simple Counter component; // A Counter Component import React , { useState } from ' react ' ; export default function Counter () { const [ count , setCount ] = useState ( 0 ); return < button onClick = {() => setCount ( count + 1 )} > C

2026-07-08 原文 →
AI 资讯

Terraform LifeCycle Rules

Day 9 of the 30 Days of AWS Terraform series focuses on Terraform Lifecycle Rules — powerful controls that decide how Terraform creates, updates, replaces, and destroys resources. What Terraform LifeCycle meta arguments are Lifecycle meta arguments allow us to control how Terraform behaves when it creates, updates, or destroys resources. They help us: Avoid downtime Protect important resources Handle changes made outside Terraform Validate configurations before and after deployment Enforcing compliance Controlling replacement behavior Lifecycle rules allow us to override default behavior safely. Lifecycle rules are Terraform-native controls applied inside a resource block: lifecycle { ... } Lifecycle Rules Covered 1️⃣ create_before_destroy — Zero Downtime Updates Problem: Terraform destroys the old resource before creating the new one → downtime. Solution: lifecycle { create_before_destroy = true } Behavior: New resource is created first Old resource is destroyed only after Ensures zero downtime 2️⃣ prevent_destroy — Protect Critical Resources This setting prevents Terraform from deleting a resource. Example If Terraform tries to destroy this resource, it will fail with an error. This is useful for: Production databases State storage buckets Important data resources 3️⃣ ignore_changes — Allow External Modifications Problem: Terraform overwrites manual or automated external changes. Solution: lifecycle { ignore_changes = [desired_capacity] } Demo: Auto Scaling Group desired capacity modified manually in AWS Console terraform apply did not revert the change Behavior: Terraform ignores changes for specified attributes. ✅ Use for: Auto Scaling Groups Resources modified by external systems Ops-driven configurations 4️⃣ replace_triggered_by — Replace When Dependency Changes Problem: Changing a dependency doesn’t always recreate dependent resources. Solution: lifecycle { replace_triggered_by = [aws_security_group.main] } Behavior: When security group changes EC2 instance i

2026-07-08 原文 →
AI 资讯

Migrating from node_exporter to Grafana Alloy, One Server at a Time

If you've been monitoring Linux servers for any length of time, there's a good chance node_exporter was the first thing you installed. It's lightweight, reliable, and exposes a huge amount of machine metrics for Prometheus to scrape. For years, it has been the default answer. As your infrastructure grows, though, your monitoring stack usually grows with it. First comes log collection. Then traces. Before long you're running node_exporter , a log shipper, and maybe another telemetry agent. Each component has its own configuration, service unit, upgrade cycle, and failure modes. Grafana Alloy changes that by consolidating those responsibilities into a single telemetry agent. This post walks through migrating from node_exporter to Alloy on a real fleet, one server at a time, while maintaining continuous visibility throughout the process. These are the exact steps that survived contact with production on the Irin monitoring stack, not the idealized version that looks clean in a diagram. TL;DR If you're already running node_exporter , don't replace it overnight. Install Grafana Alloy alongside it, configure Alloy's built-in prometheus.exporter.unix component, verify that metrics are reaching your remote Prometheus instance, and only then retire node_exporter. Migrating one server at a time minimizes risk, preserves visibility, and positions your infrastructure for logs, traces, and future telemetry without deploying additional agents. The real difference is the direction of travel Before getting started, it's worth understanding what actually changes. This isn't simply replacing one monitoring agent with another. node_exporter is a server. It listens on a port, typically 9100,and waits for Prometheus to connect and scrape metrics. That means every monitored machine needs an open endpoint, network connectivity from Prometheus, firewall rules, and scrape configurations. Alloy flips that model around. Instead of waiting for Prometheus to connect, Alloy collects metrics loca

2026-07-08 原文 →
AI 资讯

Integrating Git Submodules the Easy Way

Git submodules have a reputation for being fiddly, but most of that pain comes down to a handful of missing commands and one config flag nobody mentions. Used well, they're a clean way to embed a shared library, a design-system repo, or a common docs folder inside another project - pinned to an exact commit so nothing shifts under your feet. This guide walks through the whole lifecycle, from adding a submodule to removing it, and calls out the gotchas that bite teams in real projects. Understanding What a Submodule Actually Is Before the commands, one mental model that clears up most confusion: a submodule embeds another git repo inside yours at a fixed path, pinned to a specific commit. Your repo doesn't track the submodule's files - it tracks which commit of the submodule to check out. That single idea explains almost every quirk that follows. Adding a Submodule Adding one is a single command: git submodule add git@github.com:org/shared-lib.git vendor/shared-lib This clones the repo into vendor/shared-lib , creates a .gitmodules file describing the mapping, and stages the pinned commit (git calls this a "gitlink"). Commit both pieces: git add .gitmodules vendor/shared-lib git commit -m "chore: add shared-lib submodule" The resulting .gitmodules entry is plain text and lives in version control: [submodule "vendor/shared-lib"] path = vendor/shared-lib url = git@github.com:org/shared-lib.git branch = main The branch line is optional: it's only used later when pulling the latest changes automatically. Cloning Without the Empty-Folder Surprise The most common submodule complaint is a teammate cloning the project and finding an empty folder where the submodule should be. The fix is knowing two commands: # Clone everything in one shot git clone --recurse-submodules <your-repo-url> # Already cloned? Initialize after the fact git submodule update --init --recursive Even better, run this once per machine so git pull and git checkout keep submodules in sync automatically - a

2026-07-08 原文 →
AI 资讯

Make your content answer-first so AI models actually cite it

If you want ChatGPT or Google's AI Overviews to quote your pages, structure matters more than volume. Retrieval systems favor passages where the answer is stated plainly and can stand alone. Here's a practical way to test and fix your content. Step 1 — Define the question the page answers Write it as a literal user query. How much does a website cost for a small business in the UK? Step 2 — Extract your current answer passage Copy the first two or three sentences from your page. Paste them somewhere without any extra context. Ask yourself: Does this work as a direct answer? If it only makes sense after reading earlier paragraphs, it doesn’t pass the extraction test. Step 3 — Rewrite answer-first Lead with the conclusion, stated as a fact, then support it. Before: "We get asked about pricing a lot, and honestly it's one of the trickiest questions to answer..." After: "A small-business website in the UK typically costs £1,500–£6,000 for a brochure site and £6,000–£20,000+ for e-commerce. The price depends on three things: page count, payment functionality, and custom vs template design." Step 4 — Test extractability with a model Send the passage to an LLM and check whether it returns a clean, single answer. Use a system prompt that mimics retrieval behavior. System: You are a retrieval system. From the passage below, extract the single most direct answer to the user's question. If no self-contained answer exists, reply "NO_EXTRACTABLE_ANSWER". User question: How much does a website cost for a small business in the UK? Passage: If you get NO_EXTRACTABLE_ANSWER or a vague summary, your structure needs work. Step 5 — Reinforce with structured data Markup question and answer pages with FAQPage schema so the question/answer pairing is machine-readable as well as human-readable. json { " @context ": " https://schema.org ", "@type": "FAQPage", "mainEntity": [{ "@type": "Question", "name": "How much does a website cost for a small business in the UK?", "acceptedAnswer": { "@t

2026-07-08 原文 →
AI 资讯

دليل عملي لاختبار التحميل لواجهات API باستخدام أرتيلري

Artillery هي مجموعة أدوات مفتوحة المصدر لاختبار التحميل مبنية على Node.js. تتيح لك توليد حركة مرور عالية التزامن على واجهة برمجة التطبيقات (API) من خلال ملف YAML بسيط: تحدد مراحل التحميل، تصف تدفقات الطلبات، تشغل artillery run script.yml ، ثم تقرأ نسب زمن الاستجابة المئوية، معدلات الطلبات، وعدد الأخطاء. يشرح هذا الدليل طريقة تثبيت Artillery v2، كتابة اختبار عملي، تشغيله، استخراج النتائج بالطريقة الصحيحة في v2، وربطه بمسار CI. جرّب Apidog اليوم ما هو Artillery ومتى تستخدمه؟ ينشئ Artillery مستخدمين افتراضيين (VUs) يرسلون طلبات إلى نقاط النهاية لديك ويقيسون قدرة النظام على تحمل الحمل المستمر. المستخدم الافتراضي هو عميل مُحاكى ينفذ سيناريو خطوة بخطوة، كما يفعل مستخدم أو خدمة حقيقية. استخدم Artillery عندما تريد إجابات عملية على أسئلة الأداء مثل: كيف يتغير زمن الاستجابة p95 عند 50 طلبًا في الثانية؟ عند أي معدل وصول تبدأ الأخطاء بالظهور؟ هل تبقى واجهة API مستقرة لمدة 5 دقائق من الحمل المستمر؟ هل يتدهور الأداء تدريجيًا مع استمرار الضغط؟ الميزة الأساسية في Artillery أن الاختبار تصريحي. بدل كتابة حلقات تزامن يدويًا، تصف شكل الحمل في YAML. وبما أنه يعمل فوق Node.js، يمكنك تشغيل نفس الاختبار محليًا وفي CI. إذا كنت تقارن الأدوات، راجع ملخص أفضل أدوات اختبار التحميل و مقارنة برامج اختبار التحميل لفهم الفروقات بين k6 وJMeter وGatling وغيرها. تثبيت Artillery v2 اسم الحزمة هو artillery ، والإصدار الرئيسي الحالي هو v2. ثبته عالميًا عبر npm: npm install -g artillery@latest artillery version تحتاج إلى إصدار LTS حديث من Node.js. يعمل Artillery على Windows وmacOS وLinux. إذا كنت لا تريد تثبيت الحزمة عالميًا، استخدم npx : npx artillery@latest run script.yml كتابة اختبار Artillery يتكون ملف الاختبار من قسمين أساسيين: config : يحدد الهدف ومراحل الحمل والمتغيرات. scenarios : يحدد ما يفعله كل مستخدم افتراضي. مثال كامل: config : target : " https://api.example.com" phases : - name : " Warm up" duration : 60 arrivalRate : 5 - name : " Ramp to peak" duration : 120 arrivalRate : 5 rampTo : 50 - name : " Sustained load" duration : 300 arrivalRate : 50 maxVusers : 500 variables : productId : - " 100

2026-07-08 原文 →