Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 19 additions & 67 deletions src/collections/blog/2022/2022-05-27-debug-envoy-proxy/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,97 +52,49 @@ The default is <span className="highlight">info</span>.
<h3>Setting Envoy logs in the Helm configuration</h3>

The Consul helm chart uses <code>envoyExtraArgs:</code> to leverage Envoy command line options. One of the helpful options is <code>--component-log-level</code>. This provides granular control over setting log levels for Envoy components. In the example below, the components upstream, http, router and config are set to the debug log level. These four components are vital when debugging issues with requests between your services(sidecar proxies).
<div>
<pre>
<code>connectInject:
<Code language="yaml" codeString={`connectInject:
enabled: true
envoyExtraArgs: "--component-log-level upstream:debug,http:debug,router:debug,config:debug"</code>
</pre>
</div>
envoyExtraArgs: "--component-log-level upstream:debug,http:debug,router:debug,config:debug"`} />

If you haven't set envoyExtraArgs: in consul-values.yaml just yet, you can set the log levels on the fly by using the following kubectl command:
<div>
<pre>
<code>$ kubectl exec pod/pod-name -c container-name -- curl -X POST http://localhost:19000/logging?config=debug</code>
</pre>
</div>
<Code language="bash" codeString={`kubectl exec pod/pod-name -c container-name -- curl -X POST http://localhost:19000/logging?config=debug`} />

Example:
<div>
<pre>
<code>$ kubectl exec pod/static-client-5bf4575d9c-zr2b -c static-client -- curl -X POST http://localhost:19000/logging?config=debug</code>
</pre>
</div>
<Code language="bash" codeString={`kubectl exec pod/static-client-5bf4575d9c-zr2b -c static-client -- curl -X POST http://localhost:19000/logging?config=debug`} />

You will execute the kubectl command for each component. Make sure to append the correct component at the end of the curl command, i.e. <code>logging? component = debug</code>.
You will execute the kubectl command for each component. Make sure to append the correct component at the end of the curl command, i.e. <code>logging?&lt;component&gt;=debug</code>.
If curl is not able to be used in your pod, you can alternatively use <code>kubectl port-forward pod-name 19000</code> to make the Envoy admin accessible. From another terminal window, you can then curl to change the log levels. The output you receive in the terminal will show the modified component log levels.
<div>
<pre>
<code>$ curl -X POST http://localhost:19000/logging? component = debug</code>
</pre>
</div>
<Code language="bash" codeString={`curl -X POST http://localhost:19000/logging?upstream=debug`} />
<h3>Access Envoy logs in Kubernetes</h3>

Accessing Envoy logs via pods can be done with the following command:
<div>
<pre>
<code>$ kubectl logs --follow pod/ pod-name -c envoy-sidecar</code>
</pre>
</div>
<Code language="bash" codeString={`kubectl logs --follow pod/pod-name -c envoy-sidecar`} />

The --follow flag provides a real time observation into Envoy logs.
<h3>Setting and Accessing Envoy logs when not using Helm.</h3>

The following command will start an envoy side car proxy, set the log level to debug with -l debug and capture Envoy logs in envoy_logs.txt. The .txt file will need to be created before executing this command.
<div>
<pre>
<code>$ consul connect envoy -sidecar-for counting-1 -- -l debug --log-path envoy_logs.txt</code>
</pre>
</div>
<Code language="bash" codeString={`consul connect envoy -sidecar-for counting-1 -- -l debug --log-path envoy_logs.txt`} />

To have granular control over the Envoy components that is needed to be debugged, use the following command:
<div>
<pre>
<code>$ consul connect envoy -sidecar-for counting-1 -- --log-path envoy_logs.txt --component-log-level upstream:debug,http:debug,router:debug,config:debug</code>
</pre>
</div>
<Code language="bash" codeString={`consul connect envoy -sidecar-for counting-1 -- --log-path envoy_logs.txt --component-log-level upstream:debug,http:debug,router:debug,config:debug`} />

<h2>Find your Istio Ingress Gateway</h2>
With Istio as your gateway, you should first look at <code>VirtualService</code> objects. These can show if the hosts are registered to the gateway correctly.
<div>
<pre>
<code>$ kubectl get virtualservice -o=yaml</code>
</pre>
</div>
<Code language="bash" codeString={`kubectl get virtualservice -o=yaml`} />

However, sometimes, the <a className="highlight" href="https://envoyproxy.io">Envoy</a> inside the gateway container is not properly configured (likely due to a bug). You can dump Envoy configuration to debug this further.
<div>
<pre>
<code># find istio ingress gateway pod \
$ kubectl get pods -n istio-system -l app=istio-ingressgateway</code>
</pre>
</div>
<Code language="bash" codeString={`# find istio ingress gateway pod
kubectl get pods -n istio-system -l app=istio-ingressgateway`} />

Let's use <code>istio-ingressgateway-a93019f9dfw-l39xd</code> as an example pod name.
<div>
<pre>
<code>
# enable debugging on envoy \
$ kubectl exec --namespace=istio-system \
istio-ingressgateway-a93019f9dfw-l39xd \
-c istio-proxy -- curl -X POST \
http://localhost:15000/logging?level=debug
</code>
</pre>
</div>
<Code language="bash" codeString={`# enable debugging on envoy
kubectl exec --namespace=istio-system \\
istio-ingressgateway-a93019f9dfw-l39xd \\
-c istio-proxy -- curl -X POST \\
http://localhost:15000/logging?level=debug`} />
Then, use <code>istioctl</code> tool to dump route configuration (this will show the output from the <a href="https://www.envoyproxy.io/docs/envoy/latest/operations/admin#operations-admin-interface-config-dump"><code>/config_dump</code> admin endpoint</a> on Envoy):
<div>
<pre>
<code>
$ istioctl proxy-config routes -n istio-system -o=json \
istio-ingressgateway-a93019f9dfw-l39xd
</code>
</pre>
</div>
<Code language="bash" codeString={`istioctl proxy-config routes -n istio-system -o=json \\
istio-ingressgateway-a93019f9dfw-l39xd`} />
We hope these steps are useful to you. If you're still having trouble configuring Envoy proxy, open up a new thread on the <a href="https://discuss.meshery.io" className="highlight">community discussion forum</a> or subscribe to the <Link to="/subscribe" className="highlight">Layer5 newletter</Link> for tips and tricks.
</BlogWrapper>
36 changes: 18 additions & 18 deletions src/components/Animated-steps-list/hero/hero.style.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styled from "styled-components";
import { CopyButton, LineNo, Pre } from "../../CodeBlock";

export const HeroWrapper = styled.div`
h1 {
Expand Down Expand Up @@ -48,29 +49,28 @@ export const HeroWrapper = styled.div`
}
}

.code{
pre{
width: inherit;
margin: auto;
.code {
${Pre} {
display: flex;
flex-direction: column;
justify-content: center;
height: 6rem;

button {
top: 1rem;
}

pre {
display: flex;
height: 6rem;
align-items: center;
padding: 1rem 0.5rem 0.5rem;

@media screen and (max-width: 850px) {
height: 4.5rem;
}
@media screen and (max-width: 850px) {
height: 4.5rem;
}
}
.token-line > span:first-of-type{

${LineNo} {
display: none;
}

/* A single command centered in a tall panel: center the button on
that line, as the default placement does for a first line. */
${CopyButton} {
top: 50%;
transform: translateY(-50%);
}
}
}
p.enddescr {
Expand Down
64 changes: 58 additions & 6 deletions src/components/CodeBlock/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,62 @@
### What is the use of this CTA:
The **CodeBlock** component is a used for a custom code block
## CodeBlock

Syntax-highlighted code (Prism, Night Owl palette) with line numbers and a Copy button.

Fenced code blocks in MDX (```` ```bash ````) render through this component automatically via the `pre` mapping in `root-wrapper.js`. Use it directly in JSX or in MDX when you need a collapsible block or when the code lives in a JS string.

### Usage

```jsx
import Code from "../components/CodeBlock";

<Code codeString="mesheryctl system start" language="bash" />

// Collapsible, hidden behind a "Show Code" checkbox. `name` must be unique on the page.
<Code name="button-variants" collapsible code={codeExamples.buttonVariants} />
```

In MDX, pass multi-line code as a template literal. A shell line continuation must be written as `\\`, because a lone `\` before a newline is a JavaScript line continuation and is silently dropped:

```mdx
<Code language="bash" codeString={`kubectl exec --namespace=istio-system \\
my-pod -- curl -X POST http://localhost:15000/logging?level=debug`} />
```

### Props

| Prop | Type | Default | Description |
| ------------- | ------- | ------- | ------------------------------------------------------ |
| `codeString` | string | | Code to render. Takes precedence over `code`. |
| `code` | string | | Alias of `codeString`. |
| `language` | string | `jsx` | Prism language (`bash`, `yaml`, `json`, `go`, ...). |
| `collapsible` | boolean | `false` | Hide the code behind a "Show Code" checkbox. |
| `name` | string | | Unique id for the collapsible checkbox. |

### Layout

### How to use the CTA:
To use this CTA simply use
```
<CodeBlock codeString="print(Hello World!);" language="shell" />
CodeBlockWrapper (div) vertical rhythm: margin 1em 0, zeroed as first/last child
├── CopyButton pinned top-right, inset 0.625rem
└── Pre (pre.prism-code) margin 0, padding 0.75rem 1rem, scrolls horizontally
└── .token-line > LineNo + tokens
```

![image](https://github.com/meshery/meshery/assets/74408634/37332188-aae7-4f53-8a3b-27b0e55ed737)
Line numbers are shown only when a block has more than one line: a lone "1" numbers nothing and costs width that a shell command can use.

The Copy button overlays the code, so it must never hide a line the reader cannot get back:

- **Pointer devices** (`@media (hover: hover)`): the button is transparent until the block is hovered or the button is focused, so nothing is covered at rest.
- **Touch devices** (`@media (hover: none)`): there is no hover, so the button stays visible and `Pre` keeps a `4.5rem` gutter clear of it. That gutter is `margin-right`, not `padding-right`: a scroll container's end padding is not part of its scrollable area in Chrome, so padding leaves the last characters stranded under the button at full scroll.

Keep both halves of that rule in place when changing the button's size or position.

`CodeBlockWrapper`, `Pre`, `LineNo`, and `CopyButton` are exported. To restyle a block from a parent, interpolate them as styled-components selectors instead of targeting `pre` or `button` tags, so the override survives markup changes:

```js
import { LineNo, Pre } from "../../CodeBlock";

const Wrapper = styled.div`
${Pre} { height: 6rem; }
${LineNo} { display: none; }
`;
```
42 changes: 21 additions & 21 deletions src/components/CodeBlock/copy-to-clipboard.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
// https://github.com/gatsbyjs/gatsby/blob/master/www/src/utils/copy-to-clipboard.js
// Adapted from https://github.com/gatsbyjs/gatsby/blob/master/www/src/utils/copy-to-clipboard.js

export const copyToClipboard = str => {
// Copies `str` to the clipboard. Resolves when the copy succeeded and rejects
// with an Error when it did not, including on the legacy fallback path.
export const copyToClipboard = async (str) => {
const clipboard = window.navigator.clipboard;
/*
* fallback to older browsers (including Safari)
* if clipboard API not supported
*/
if (!clipboard || typeof clipboard.writeText !== "function") {
const textarea = document.createElement("textarea");
textarea.value = str;
textarea.setAttribute("readonly", true);
textarea.setAttribute("contenteditable", true);
textarea.style.position = "absolute";
textarea.style.left = "-9999px";
document.body.appendChild(textarea);
if (clipboard && typeof clipboard.writeText === "function") {
await clipboard.writeText(str);
return;
}

// Fallback for browsers without the async Clipboard API.
const textarea = document.createElement("textarea");
textarea.value = str;
textarea.setAttribute("readonly", "");
textarea.style.position = "absolute";
textarea.style.left = "-9999px";
document.body.appendChild(textarea);
try {
textarea.select();
const range = document.createRange();
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
textarea.setSelectionRange(0, textarea.value.length);
document.execCommand("copy");
if (!document.execCommand("copy")) {
throw new Error("document.execCommand(\"copy\") was rejected by the browser");
}
} finally {
document.body.removeChild(textarea);
return Promise.resolve(true);
}
return clipboard.writeText(str);
};
Loading