<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */
package org.apache.logging.log4j.core;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;

import com.google.monitoring.runtime.instrumentation.AllocationRecorder;
import com.google.monitoring.runtime.instrumentation.Sampler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
import org.apache.logging.log4j.core.util.Constants;
import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Verifies steady state logging is GC-free.
 *
 * @see <a href="https://github.com/google/allocation-instrumenter">https://github.com/google/allocation-instrumenter</a>
 */
public class GcFreeLoggingTest {

    private static class MyCharSeq implements CharSequence {
        final String seq = GcFreeLoggingTest.class.toString();

        @Override
        public int length() {
            return seq.length();
        }

        @Override
        public char charAt(final int index) {
            return seq.charAt(index);
        }

        @Override
        public CharSequence subSequence(final int start, final int end) {
            return seq.subSequence(start, end);
        }

        @Override
        public String toString() {
            System.err.println("TEMP OBJECT CREATED!");
            throw new IllegalStateException("TEMP OBJECT CREATED!");
        }
    }

    @Test
    public void testNoAllocationDuringSteadyStateLogging() throws Throwable {
        if (!Constants.ENABLE_THREADLOCALS || !Constants.ENABLE_DIRECT_ENCODERS) {
            return;
        }
        final String javaHome = System.getProperty("java.home");
        final String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
        final String classpath = System.getProperty("java.class.path");
        final String javaagent = "-javaagent:" + agentJar();

        final File tempFile = File.createTempFile("allocations", ".txt");
        tempFile.deleteOnExit();

        final ProcessBuilder builder = new ProcessBuilder( //
                javaBin, javaagent, "-cp", classpath, GcFreeLoggingTest.class.getName());
        builder.redirectError(ProcessBuilder.Redirect.to(tempFile));
        builder.redirectOutput(ProcessBuilder.Redirect.to(tempFile));
        final Process process = builder.start();
        process.waitFor();
        process.exitValue();

        final String output = new String(Files.readAllBytes(tempFile.toPath()));
        final String NEWLINE = System.getProperty("line.separator");
        assertEquals("FATAL o.a.l.l.c.GcFreeLoggingTest [main]  This message is logged to the console"
                + NEWLINE, output);
    }

    /**
     * This code runs in a separate process, instrumented with the Google Allocation Instrumenter.
     */
    public static void main(String[] args) throws Exception {
        System.setProperty("log4j2.enable.threadlocals", "true");
        System.setProperty("log4j2.is.webapp", "false");
        System.setProperty("log4j.configurationFile", "gcFreeLogging.xml");
        System.setProperty("Log4jContextSelector", AsyncLoggerContextSelector.class.getName());

        assertTrue("Constants.ENABLE_THREADLOCALS", Constants.ENABLE_THREADLOCALS);
        assertFalse("Constants.IS_WEB_APP", Constants.IS_WEB_APP);

        MyCharSeq myCharSeq = new MyCharSeq();
        MarkerManager.getMarker("test"); // initial creation, value is cached

        // initialize LoggerContext etc.
        // This is not steady-state logging and will allocate objects.
        final Logger logger = LogManager.getLogger(GcFreeLoggingTest.class.getName());
        logger.debug("debug not set");
        logger.fatal("This message is logged to the console");
        logger.error("Sample error message");
        logger.error("Test parameterized message {}", "param");
<commit_msg>ignore spurious output to the console and only fail if the text indicates that an object was allocated<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */
package org.apache.logging.log4j.core;

import java.io.File;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
import org.apache.logging.log4j.core.util.Constants;
import org.junit.Test;

import com.google.monitoring.runtime.instrumentation.AllocationRecorder;
import com.google.monitoring.runtime.instrumentation.Sampler;

import static org.junit.Assert.*;

/**
 * Verifies steady state logging is GC-free.
 *
 * @see <a href="https://github.com/google/allocation-instrumenter">https://github.com/google/allocation-instrumenter</a>
 */
public class GcFreeLoggingTest {

    private static class MyCharSeq implements CharSequence {
        final String seq = GcFreeLoggingTest.class.toString();

        @Override
        public int length() {
            return seq.length();
        }

        @Override
        public char charAt(final int index) {
            return seq.charAt(index);
        }

        @Override
        public CharSequence subSequence(final int start, final int end) {
            return seq.subSequence(start, end);
        }

        @Override
        public String toString() {
            System.err.println("TEMP OBJECT CREATED!");
            throw new IllegalStateException("TEMP OBJECT CREATED!");
        }
    }

    @Test
    public void testNoAllocationDuringSteadyStateLogging() throws Throwable {
        if (!Constants.ENABLE_THREADLOCALS || !Constants.ENABLE_DIRECT_ENCODERS) {
            return;
        }
        final String javaHome = System.getProperty("java.home");
        final String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
        final String classpath = System.getProperty("java.class.path");
        final String javaagent = "-javaagent:" + agentJar();

        final File tempFile = File.createTempFile("allocations", ".txt");
        tempFile.deleteOnExit();

        final ProcessBuilder builder = new ProcessBuilder( //
                javaBin, javaagent, "-cp", classpath, GcFreeLoggingTest.class.getName());
        builder.redirectError(ProcessBuilder.Redirect.to(tempFile));
        builder.redirectOutput(ProcessBuilder.Redirect.to(tempFile));
        final Process process = builder.start();
        process.waitFor();
        process.exitValue();

        final List<String> lines = Files.readAllLines(tempFile.toPath(), Charset.defaultCharset());
        assertEquals("FATAL o.a.l.l.c.GcFreeLoggingTest [main]  This message is logged to the console",
                lines.get(0));

        for (int i = 1; i < lines.size(); i++) {
            final String line = lines.get(i);
            assertFalse(line, line.contains("allocated") || line.contains("array"));
        }
    }

    /**
     * This code runs in a separate process, instrumented with the Google Allocation Instrumenter.
     */
    public static void main(String[] args) throws Exception {
        System.setProperty("log4j2.enable.threadlocals", "true");
        System.setProperty("log4j2.is.webapp", "false");
        System.setProperty("log4j.configurationFile", "gcFreeLogging.xml");
        System.setProperty("Log4jContextSelector", AsyncLoggerContextSelector.class.getName());

        assertTrue("Constants.ENABLE_THREADLOCALS", Constants.ENABLE_THREADLOCALS);
        assertFalse("Constants.IS_WEB_APP", Constants.IS_WEB_APP);

        MyCharSeq myCharSeq = new MyCharSeq();
        MarkerManager.getMarker("test"); // initial creation, value is cached

        // initialize LoggerContext etc.
        // This is not steady-state logging and will allocate objects.
        final Logger logger = LogManager.getLogger(GcFreeLoggingTest.class.getName());
        logger.debug("debug not set");
        logger.fatal("This message is logged to the console");
        logger.error("Sample error message");
        logger.error("Test parameterized message {}", "param");

{'fraction_non_alphanumeric': 0.10276356192425794, 'fraction_numerical': 0.003480040941658137, 'mean_word_length': 3.208010335917313, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 8, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '985195', 'n_tokens_mistral': 2597, 'n_tokens_neox': 2557, 'n_words': 734}