List open or listening ports

You started a service, you can’t tell whether it actually bound to its port, and you want to see what’s listening — or you want to find out which process is squatting on port 8080. Two one-liners, two operating systems:

macOS

1
lsof -nP -i4TCP

RedHat / CentOS 7

1
netstat -tulpn

What the flags do: lsof -nP turns off DNS and port-name resolution (so you see 192.168.1.5:443 instead of app-server.local:https — faster and unambiguous). -i4TCP filters to IPv4 TCP sockets. For netstat -tulpn: t = TCP, u = UDP, l = listening only, p = show the PID/process, n = numeric (no DNS).


A few useful additions.

On modern Linux, prefer ss over netstat. The net-tools package that ships netstat is largely deprecated — most distros have moved to iproute2‘s ss (socket statistics). It’s faster on busy machines (reads from netlink instead of /proc) and uses the same flags you already know:

1
ss -tulpn

If you’ve been muscle-memory-typing netstat for years, the migration is one character. Same flags, same shape, modern implementation.

Listening-only on macOS. lsof -i4TCP shows every TCP connection — listeners and established. To narrow to just the things accepting new connections, add -sTCP:LISTEN:

1
2
3
4
5
# All listening TCP sockets (IPv4 + IPv6)
lsof -nP -iTCP -sTCP:LISTEN

# Add UDP for the full picture
lsof -nP -iUDP

The question you actually want answered: “what’s on port 8080?” Three flavours of the same question:

1
2
3
4
5
6
7
8
# macOS / Linux
lsof -i :8080

# Linux (modern)
ss -tulpn | grep :8080

# Linux (also handy — kill-by-port)
sudo fuser -k 8080/tcp

The last one is the nuclear option: fuser -k kills whoever has the port. Useful when a stale process is holding it and you don’t care about graceful shutdown.

Run it as root if you want to see other users’ processes. Without sudo, lsof, netstat -p, and ss -p only show process names for processes you own. If you see a port listed as LISTEN but the PID column is blank, that’s the symptom — re-run with sudo and the owner pops out.

Windows. The closest equivalent on Windows is netstat -ano from cmd (the -o shows the PID; cross-reference in Task Manager or with tasklist /fi “PID eq 1234”). PowerShell users get something nicer — Get-NetTCPConnection returns proper objects you can pipe and filter:

1
Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess

Pair that with Get-Process -Id $pid to translate OwningProcess back to a process name. 🔌

Posted in Bash, Operating System | Comments Off on List open or listening ports

MongoDB Notes

If you’re storing binary files inside MongoDB, the convention is called GridFS. It splits each logical file into two collections: a metadata document and a sequence of binary chunks. This post is a cheat sheet for inspecting and tweaking those documents from the Mongo shell. 🍃

When using MongoDB to store files, we have two collections:

  1. The place where MongoDB stores the file metadata: store.files
  2. And the place where MongoDB stores the file content: store.chunks

Depending on the size of the file, one entry in store.files can point to many entries in store.chunks. The bigger the file, the more entries you’ll encounter.

1
2
3
4
5
6
7
8
// Show all / list all entries from store.files
db.getCollection('store.files').find({});

// Show only a particular entry from store.files
db.getCollection('store.files').find({ _id: ObjectId("5b02d232cbce1d07e08401c7") });

// The same can be used for store.chunks.
db.getCollection('store.chunks').find({});

The metadata fields in store.files can be augmented at query time (the new field exists only in the result, not in the database):

1
2
3
4
db.getCollection('store.files').aggregate([
    { $match: { _id: ObjectId("5b02d232cbce1d07e08401c7") } },
    { $addFields: { 'key_reference': '1234' } }
]);

Or we can do an update on store.files, which actually persists the new field into the database:

1
2
3
4
db.getCollection('store.files').updateMany(
    { _id: ObjectId("5b02d232cbce1d07e08401c7") },
    { $set: { 'key_reference': '1234' } }
);

A few useful additions.

Why files are split into chunks. MongoDB’s per-document hard limit is 16 MB. GridFS works around that by splitting any file larger than the chunk size into many small chunk documents and writing one metadata doc that links them together. The default chunk size is 255 KB, configurable per bucket. So a 10 MB upload becomes one *.files doc and roughly 40 *.chunks docs, all sharing the same files_id. To inspect that relationship for a specific file:

1
2
3
db.getCollection('store.chunks')
    .find({ files_id: ObjectId("5b02d232cbce1d07e08401c7") })
    .sort({ n: 1 });   // n is the chunk index, 0..N-1

The bucket name store.* is custom. The default GridFS bucket is named fs, so out of the box you’d see fs.files and fs.chunks. The bucket name is whatever the application set when it opened the GridFS handle. If your app uses store, replace fs with store in any docs example you find online.

Putting and getting files in the first place. The shell snippets above are for inspecting files that are already there — they don’t help you upload or download the binary content. For that, use the mongofiles CLI or the driver-level GridFS API:

1
2
3
4
5
6
7
8
# Upload
mongofiles --uri "mongodb://localhost/mydb" --prefix store put /path/to/file.pdf

# Download
mongofiles --uri "mongodb://localhost/mydb" --prefix store get file.pdf

# List
mongofiles --uri "mongodb://localhost/mydb" --prefix store list

From application code, every official driver has a GridFS class — GridFSBucket in Node and Java, GridFS in PyMongo, IGridFSBucket in C#. They handle the chunking and reassembly for you.

Don’t delete files by hand. A common pitfall: deleting a row from store.files directly leaves the matching chunks orphaned in store.chunks, slowly bloating the collection. Either use mongofiles delete <filename>, or your driver’s GridFSBucket.delete(fileId), both of which remove the metadata and the chunks atomically.

Should you actually use GridFS? A practical heads-up: if your files are bigger than 16 MB and you already use MongoDB, GridFS is a reasonable fit and keeps backups simple. But for most modern stacks, putting the bytes in object storage (S3, GCS, MinIO, R2) and keeping only a URL or key in MongoDB is cheaper, faster, and easier to scale. GridFS is most defensible when you genuinely want files transactionally co-located with the database — e.g. mobile/embedded scenarios, or when network egress to S3 is a non-starter. 💡

Posted in Database | Comments Off on MongoDB Notes

CentOS 6 repo Settings

To fix repo settings in CentOS 6

1. make sure there is no proxy or funny settings in
vi /etc/yum.conf

2. There are a couple of files within /etc/yum.repos.d/. Make sure the url are correct (accessible) and enabled=1
ll /etc/yum.repos.d/

3. Cleanup the repo, list and retest
yum –enablerepo=base clean metadata;
yum repolist all
yum search java-1.8.0-openjdk

Posted in Linux | Comments Off on CentOS 6 repo Settings

Show Linux Partition Tree Mountpoint and If SSD

1
lsblk -o TYPE,NAME,KNAME,UUID,MOUNTPOINT,SIZE,ROTA
Posted in Linux | Comments Off on Show Linux Partition Tree Mountpoint and If SSD

Setting log4j log level programmatically

Sometimes you don’t want to ship a log4j.properties file — you want to spin up logging in code. Useful inside unit tests, one-off debug runs, or anywhere you want to flip log levels at runtime. Here’s a self-contained setupLog4j() that wipes any existing config, installs a console appender with a pattern, sets the root level to DEBUG, and binds a logger for your class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

private static void setupLog4j() {
        System.out.println("setupLog4j");
        BasicConfigurator.resetConfiguration();
        // Start clean.
        Logger.getRootLogger().removeAllAppenders();
        // Create appender
        ConsoleAppender console = new ConsoleAppender();
        // Configure the appender
        String PATTERN = "%d --[ %p ] %l: %m%n";
        console.setLayout(new PatternLayout(PATTERN));
        console.activateOptions();
        console.setName("stdout");
        Logger.getRootLogger().setLevel(Level.DEBUG);
        BasicConfigurator.configure(console);
        LOG = Logger.getLogger(MinerTest.class);
}

Replace MinerTest.class with your own class — it’s just the logger name (Log4j conventionally uses the fully-qualified class name so output stays organised by package).


A few useful additions.

This is Log4j 1.x — and Log4j 1.x is end-of-life. The package above is org.apache.log4j. Log4j 1.x reached EOL in August 2015 and has unpatched CVEs against it. If you’re starting something new, use Log4j 2 (org.apache.logging.log4j) or SLF4J with Logback. Keep this snippet around as a recipe for legacy projects, but don’t pick Log4j 1.x for anything fresh.

Set the level for one package, not the whole app. Logger.getRootLogger().setLevel(Level.DEBUG) turns DEBUG on globally — that floods everything, including third-party libraries. Usually you only want DEBUG for your own code:

1
2
Logger.getLogger("com.acme.miner").setLevel(Level.DEBUG);
Logger.getLogger("org.springframework").setLevel(Level.WARN); // tame the framework

Same idea in Log4j 2. The API is different — there’s no BasicConfigurator; instead you talk to the LoggerContext / Configurator:

1
2
3
4
5
6
7
8
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;

// Set the level for one package at runtime:
Configurator.setLevel("com.acme.miner", Level.DEBUG);

// Or for the root logger:
Configurator.setRootLevel(Level.DEBUG);

For the full “build a config from scratch” equivalent, see Log4j 2’s ConfigurationBuilder — the API is more verbose but lets you compose appenders, layouts, and loggers programmatically.

Using SLF4J / Logback? If your codebase logs via org.slf4j.Logger with Logback under the hood (very common), you flip levels through Logback’s own classes — SLF4J itself has no level-setting API:

1
2
3
4
5
6
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;

Logger logger = (Logger) LoggerFactory.getLogger("com.acme.miner");
logger.setLevel(Level.DEBUG);

The cast from org.slf4j.Logger to ch.qos.logback.classic.Logger is the giveaway — SLF4J is just a facade; the level lives on the implementation. 🪵

Posted in java | Comments Off on Setting log4j log level programmatically

Print java stack trace from anywhere

Need to know which code calls a specific location? Dump the stack trace:

1
2
3
4
import org.apache.commons.lang3.exception.ExceptionUtils;

// ...somewhere in your method:
LOG.trace(ExceptionUtils.getStackTrace(new Throwable()));

You’re constructing a Throwable just to capture the current stack — you’re not throwing it. ExceptionUtils.getStackTrace turns the captured frames into a multi-line String that’s safe to hand to a logger. Make sure your log config has trace level enabled for whichever logger LOG belongs to, otherwise the line silently does nothing.


A few useful additions.

When this beats a breakpoint. You’d reach for this over a debugger when (a) you’re chasing a bug that only shows up in production, (b) the call happens in async / event-driven code where breakpoints are awkward, or (c) a method is called from many places and you want to know which path is firing. Sprinkle a few of these in, run the workload, then read the log.

No Apache Commons? Stdlib will do. ExceptionUtils lives in org.apache.commons.lang3, which is a separate dependency. If you don’t have it on the classpath you can fall back to plain JDK:

1
2
3
4
5
6
7
8
9
10
// Option 1 — quick and dirty, writes to stderr (not your logger):
new Throwable().printStackTrace();

// Option 2 — get the trace as a String you can log:
import java.io.StringWriter;
import java.io.PrintWriter;

StringWriter sw = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(sw));
LOG.trace(sw.toString());

Java 9+: StackWalker is the modern API. If you actually want to inspect the frames programmatically (instead of just dumping a blob of text), use StackWalker — it’s lazy, so it doesn’t eagerly materialize every frame the way new Throwable().getStackTrace() does:

1
2
3
4
5
6
7
import java.lang.StackWalker;
import java.lang.StackWalker.StackFrame;
import java.util.stream.Collectors;

String trace = StackWalker.getInstance()
        .walk(s -> s.map(StackFrame::toString).collect(Collectors.joining("\n")));
LOG.trace(trace);

For a one-line debug print though, the original Apache Commons one-liner is still hard to beat. 🪵

Posted in java | Comments Off on Print java stack trace from anywhere

Knowing your exception class name

You’re staring at a generic catch (Exception e) and you don’t know which actual exception is being thrown. The trick is to log the runtime class so you can replace the generic catch with a specific one:

1
2
3
4
5
} catch (Exception e) {
    LOG.error("SQL error when processing " + requestId
        + ". Exception class: " + e.getClass().getCanonicalName());
    throw e;
}

Run the failing scenario, read the log, and you’ll see something like java.sql.SQLIntegrityConstraintViolationException — now you can write a specific catch for it.


A few useful additions.

Three flavours of class name. The Class object exposes three different name accessors and they behave differently for inner / anonymous classes:

  • getName() — JVM internal name. Inner classes show up with a dollar sign: com.acme.Outer$Inner.
  • getCanonicalName() — Java source-style name. Inner classes use a dot: com.acme.Outer.Inner. Returns null for anonymous and local classes.
  • getSimpleName() — just the leaf name, no package: Inner. Empty string for anonymous classes.

For diagnostics, getName() is usually safest because it never returns null. getCanonicalName() reads more naturally in logs but bites you the moment an exception comes from an anonymous class.

If you’re using SLF4J, you don’t need to format the exception yourself. Pass the throwable as the last argument and SLF4J logs the class name and the full stack trace for free:

1
2
3
4
} catch (Exception e) {
    LOG.error("SQL error when processing {}", requestId, e);
    throw e;
}

That single line gives you more diagnostic information than the original — no manual getClass() call needed.

Once you know the class, prefer multi-catch over a generic catch (Exception). Java 7+ supports listing several exception types in one block:

1
2
3
4
} catch (SQLIntegrityConstraintViolationException | DataAccessException e) {
    LOG.error("SQL error when processing {}", requestId, e);
    throw e;
}

This narrows what you’re handling, makes the intent obvious to readers, and lets your linter actually help you. The original “log the class name” trick is a great discovery tool — but once you’ve discovered, replace it with a specific catch. 🪲

Posted in java | Tagged | Comments Off on Knowing your exception class name

SELinux directory permission

To check SELinux directory permission you need to -z for example

1
ls -Z /var/www/html

If something is incorrect you can re-adjust some of the directory permission:

1
chcon -R -t httpd_sys_content_t /var/www/html
Posted in Linux, Operating System | Comments Off on SELinux directory permission

RedHat / Centos Firewall

To add an exception to firewall
In RedHat/CentOS 6

1
2
3
4
5
iptables --line -vnL
iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.0.0/16 -j ACCEPT
iptables -D INPUT -p tcp -s 192.168.0.0/16 -j ACCEPT
service iptables save

In RedHat/CentOS 7

1
2
3
4
5
6
firewall-cmd --list-all
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-source=192.168.0.0/16
firewall-cmd --permanent --zone=public --remove-source=192.168.0.0/16
firewall-cmd --reload
systemctl disable firewalld
Posted in Linux, Operating System | Comments Off on RedHat / Centos Firewall

Bash string comparison

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/bin/bash

function test(){
echo ""
echo "TEST $1"
echo "VAR_1: $VAR_1 VAR_2: $VAR_2 "
if [ "$VAR_1" = "false" ]; then echo " VAR_1 is false"; fi
if [ "$VAR_2" = "false" ]; then echo " VAR_2 is false"; fi
if [ "$VAR_1" = "false" ] || [ "$VAR_2" = "false" ]; then echo " At least one is false"; fi
}
VAR_1='true';
VAR_2='true';
test 1

VAR_1='true';
VAR_2='false';
test 2

VAR_1='false';
VAR_2='false';
test 3

function test2(){
echo ""
echo "TEST $1"
echo "VAR_3: $VAR_3 VAR_4: $VAR_4 "
[ -n "$VAR_3" ] &amp;&amp; echo " VAR_3 is not null"
[ -z "$VAR_3" ] &amp;&amp; echo " VAR_3 is null"
[ -n "$VAR_4" ] &amp;&amp; echo " VAR_4 is not null"
[ -z "$VAR_4" ] &amp;&amp; echo " VAR_4 is null"
}

VAR_3=""
VAR_4=""
test2 4

VAR_3="3"
VAR_4=""
test2 5
<h4>Result</h4>
$ /c/tmp/bashtest.sh

TEST 1
VAR_1: true VAR_2: true

TEST 2
VAR_1: true VAR_2: false
VAR_2 is false
At least one is false

TEST 3
VAR_1: false VAR_2: false
VAR_1 is false
VAR_2 is false
At least one is false

TEST 4
VAR_3: VAR_4:
VAR_3 is null
VAR_4 is null

TEST 5
VAR_3: 3 VAR_4:
VAR_3 is not null
VAR_4 is null
Posted in Bash, Linux | Comments Off on Bash string comparison